Grails displaying values from two tables using primary and foreign keys - sql

This is, I hope, probably quite obvious but I can't find an example that I think answers my issue.
I have an SQL database that I cant modify and within it are two tables, linked with primary/foreign keys (test_scenario and test_exec_queue respectively, so the PK value from test_scenario can show up many times within test_exec_queue) and when I display the data on screen I want it to, instead of displaying the FK value from test_exec_queue I want it to use that to get testScenarioName from the test_scenario table and display that instead.
So far my class looks like this but I've no idea what to put in to do the above logic, or do I do this somewhere else? In the controller? Any help appreciated
class TestExecQueue {
static constraints = {
testscenarioid(blank:false, editable:false)
myPriority(inList:[0,1,2,3,4], blank:false)
myState(inList:["READY"], blank:false)
}
static mapping = {
table "test_exec_queue"
version false
columns{
id column:"test_exec_queue_id"
testscenarioid column:"test_scenario_id"
myPriority column:"Priority"
myState column:"State"
}
}
Integer testscenarioid
Integer myPriority
String myState
}

You need to create a class which maps the test_scenario table in addition to the TestExecQueue class you've already implemented.
In your TestExecQueue class, you would link to the scenario by class, rather than by an integer field:
class TestExecQueue {
static mapping = {
scenario column:'test_scenario_id'
}
TestScenario scenario
}
Note: This is one example of mapping the relationship, you should review the Domain Modeling section of the Grails Documentation for other options.
The display of the classes is entirely dependent on your controllers and views, and that would need more elaboration on your part to answer clearly. One option is to set the public toString() methods on the classes that will be printed.

Related

NullObject Pattern: How to handle fields?

Suppose we have Book class which contains year_published public field. If I want to implement NullObject design pattern, I will need to define NullBook class which behaves same as Book but does not do anything.
Question is, what should be the behavior of NullBook when it's fields are being assigned?
Book book = find_book(id_value); //this method returns a NullBook instance because it cannot find the book
book.year_published = 2016; //What should we do here?!
The first thing you should do is to make your properties private.
class NullBook {
private year_published;
// OR solution2 private year_published = null;
public setYearPublished(year_published) {
this.year_published = null;
// OR solution2 do nothing!
}
}
You can also define the field private in the parent class, so the children will have to implement the setter to acces the field
class Book {
private year_published;
public setYearPublished(year_published) {
this.year_published = year_published;
}
}
class NullBook extends Book {
public setYearPublished(year_published) {
parent::setYearPublished(null);
}
}
Why use getters and setters?
https://stackoverflow.com/a/1568230/2377164
Thing is: patterns are about balancing. Yes, it is in general good practice to not return null, but to having else to return; but well: what is returned should still make sense!
And to a certain degree, I don't see how having a "NullBook" really helps with the design of your application. Especially as you allow access to various internal fields. You exactly asked the correct question: what should be the published year, or author, or ... of such a "NullBook"?!
What happens for example when some piece of code does a "lookup" on books from different "sources"; and then tries to sort those books on the published year. You sure don't want your NullBook to ever be part of such data.
Thus I fail to see the value in having this class, to the contrary: I see it creating a potential for "interesting" bugs; thus my answer is: step back and re-consider if you really need that class.
There are alternatives to null-replacing objects: maybe your language allows for Optionals; or, you rework those methods that could return null ... to return a collection/array of books; and in doubt: that list/array is simply empty.
Long story short: allowing other classes direct access to private fields is a much more of an import design smell; so you shouldn't be too focused on NullObjects, while giving up on such essential things as Information Hiding so easily on the other hand.

Laravel relationship : hasMany of different classes

Consider the following scenario in Laravel 4.1
there is a Set model that may have many items (sorted by precedence, but this can be put aside for now)
each of these items can be of a different "kind" (think of a bag (the Set) that contains keys,wallet,cigs...)
Ideally I would like to achieve the following:
have a simplified, eager-loadable relationship between a Set and its items (explained better below)
keep the item models DRY (ideally each item extends an abstract class with basic boilerplate code)
To better illustrate what I have in mind:
class Set extends Eloquent {
// ...
public function items() {
// provides a "transparent" method to access ALL of its items ... no matter what class
}
}
and
class SubItemOne extends Item { // ... }
class SubItemTwo extends Item { // ... }
abstract class Item extends Eloquent {
public function set() {
return $this->belongsTo('Set');
}
}
because at its core each sub-class shares a lot in common with the others (think of: they can all be moved around in the set, or they can be attached an image etc. ... all of which could be defined within the abstract Item class).
Essentially, I want to be able to access all of the items belonging to my Set in situations like
Set::with('items')->find(1);
but I'm really unsure about what kind of relationship to use for the 'inverse'.
Things I've considered so far:
take out the subclassed models and just keep one Item model with a "item_kind" flag to identify its type. Have each item define a relationship to another class based on this flag... (already sounds butt-ugly to me)
polymorphic relations (including the new N-2-N introduced in L 4.1) although they don't really seem to be thought for this specific scenario: especially N2N still doesn't solve the problem of accessing ALL the items via one simple relation
ditch the eager-loadable relation and write a custom "get_items()" method that would access the individual relationships (as in ->subitemones(), ->subitemtwos() etc ) but this seems like a rather dumb way to solve this problem (i really would like to be able to access the relationship within the query builder)
I'm kinda stuck here but I can't believe I'm the only one facing this situation... I'm really hoping for a "best practice" kind of suggestion here!
You could consinder maping your class hierarcy to DB hierarcy. There are many ways to represent inheritance in your DB schema.
Considering your scenario you can have the following tables:
Set: This entity maps your parent class and stores all common information of a Set Item (eg Position etc)
SubItemOne: Extends the "set" entity, and stores only the additional information specific to this type.
SubitemTwo... etc
SubItemXXX have a 1:1 relationship with the Set entity. All you have to do is a simple JOIN to merge SubItemXXX and Set
You can read more at: How can you represent inheritance in a database?

Mapping of Interface is Not Supported, But Linq-Sql Object Already Implements Property

So, I created a DataContext (Linq-Sql) in VS from an existing database. It has a table called Users, thus I have a User object. In particular, I want to focus on the UserID and Username properties.
Now, I have an interface:
interface IUser
{
int Id { get; }
string Username { get; }
}
I want to create a partial User class and implement IUser. The reason for this is so that I can treat any User as an IUser in many places and not be concerned about the precise User class:
public partial class User : IUser
{
public int Id
{
get { return UserID; }
}
}
I don't implement the Username get property because I know that the entity object already implements it.
When I have a query like dc.Users.SingleOrDefault(p => p.Id == 5); I know that it's an error because it'll translate that call to an SQL statement and it's going to try to find the Id column, which doesn't exist - UserID exists. So I understand this mapping issue.
When I query dc.Users.SingleOrDefault(p => p.Username == "admin"), it also throws an error, BUT Username IS indeed an existing column in the database, so my impression is that no custom/additional mapping needs to take place. What am I missing?
Can someone point me to a good source on how to combat Linq vs. partial classes implement a custom interface?
Update Question:
Before I try it, does anyone know if "rigging" the datacontext.designer.cs file with our custom interfaces (to implement to the classes themselves instead of in a separate partial class file) will work? Is there a consequence of doing this?
I've come across this before using Generics and LINQ, and the way I solved it was to change p.Id == 5 to p.Id.Equals(5) and LINQ was able to map the query.
In regards to rigging autogenerated code, I have done this in my projects, the only annoyance is having to type all the interfaces again if you regenerate your DBML file. I looked in to dynamically adding interfaces to classes and found this SO post, but I haven't tried it out yet:
What is the nicest way to dynamically implement an interface in C#?
Either way, re-typing is a much better trade off for us right now as we've been able to remove a lot of duplication in our implementation code with this method.
Unfortunately I'm not experienced enough with LINQ or .NET to explain why Equals() works when == does not :)

Accept Interface into Collection (Covariance) troubles with nHibernate

I am using Fluent nHibernate for my persistence layer in an ASP.NET MVC application, and I have come across a bit of a quandry.
I have a situation where I need to use an abstraction to store objects into a collection, in this situation, an interface is the most logical choice if you are looking at a pure C# perspective.
Basically, an object (Item) can have Requirements. A requirement can be many things. In a native C# situation, I would merely accomplish this with the following code.
interface IRequirement
{
// methods and properties neccessary for evaluation
}
class Item
{
virtual int Id { get; set; }
virtual IList<IRequirement> Requirements { get; set; }
}
A crude example. This works fine in native C# - however because the objects have to be stored in a database, it becomes a bit more complicated than that. Each object that implements IRequirement could be a completely different kind of object. Since nHibernate (or any other ORM that I have discovered) cannot really understand how to serialize an interface, I cannot think of, for the life of me, how to approach this scenario. I mean, I understand the problem.
This makes no sense to the database/orm. I understand completely why, too.
class SomeKindOfObject
{
virtual int Id { get; set; }
// ... some other methods relative to this base type
}
class OneRequirement : SomeKindOfObject, IRequirement
{
virtual string Name { get; set; }
// some more methods and properties
}
class AnotherKindOfObject
{
virtual int Id { get; set; }
// ... more methods and properties, different from SomeKindOfObject
}
class AnotherRequirement : AnotherKindOfObject, IRequirement
{
// yet more methods and properties relative to AnotherKindOfObject's intentive hierarchy
}
class OneRequirementMap : ClassMap<OneRequirement>
{
// etc
Table("OneRequirement");
}
class AnotherRequirementMap : ClassMap<AnotherRequirement>
{
//
Table("OtherRequirements");
}
class ItemMap : ClassMap<Item>
{
// ... Now we have a problem.
Map( x => x.Requirements ) // does not compute...
// additional mapping
}
So, does anyone have any ideas? I cannot seem to use generics, either, so making a basic Requirement<T> type seems out. I mean the code works and runs, but the ORM cannot grasp it. I realize what I am asking here is probably impossible, but all I can do is ask.
I would also like to add, I do not have much experience with nHibernate, only Fluent nHibernate, but I have been made aware that both communities are very good and so I am tagging this as both. But my mapping at present is 100% 'fluent'.
Edit
I actually discovered Programming to interfaces while mapping with Fluent NHibernate that touches on this a bit, but I'm still not sure it is applicable to my scenario. Any help is appreciated.
UPDATE (02/02/2011)
I'm adding this update in response to some of the answers posted, as my results are ... a little awkward.
Taking the advice, and doing more research, I've designed a basic interface.
interface IRequirement
{
// ... Same as it always was
}
and now I establish my class mapping..
class IRequirementMap : ClassMap<IRequirement>
{
public IRequirementMap()
{
Id( x => x.Id );
UseUnionSubclassForInheritanceMapping();
Table("Requirements");
}
}
And then I map something that implements it. This is where it gets very freaky.
class ObjectThatImplementsRequirementMap : ClassMap<ObjectThatImplementsRequirement>
{
ObjectThatImplementsRequirementMap()
{
Id(x => x.Id); // Yes, I am base-class mapping it.
// other properties
Table("ObjectImplementingRequirement");
}
}
class AnotherObjectThatHasRequirementMap : ClassMap<AnotherObjectThatHasRequirement>
{
AnotherObjectThatHasRequirementMap ()
{
Id(x => x.Id); // Yes, I am base-class mapping it.
// other properties
Table("AnotheObjectImplementingRequirement");
}
}
This is not what people have suggested, but it was my first approach. Though I did it because I got some very freaky results. Results that really make no sense to me.
It Actually Works... Sort Of
Running the following code yields unanticipated results.
// setup ISession
// setup Transaction
var requirements = new <IRequirement>
{
new ObjectThatImplementsRequirement
{
// properties, etc..
},
new AnotherObjectThatHasRequirement
{
// other properties.
}
}
// add to session.
// commit transaction.
// close writing block.
// setup new session
// setup new transaction
var requireables = session.Query<IRequirable>();
foreach(var requireable in requireables)
Console.WriteLine( requireable.Id );
Now things get freaky. I get the results...
1
1
This makes no sense to me. It shouldn't work. I can even query the individual properties of each object, and they have retained their type. Even if I run the insertion, close the application, then run the retrieval (so as to avoid the possibility of caching), they still have the right types. But the following does not work.
class SomethingThatHasRequireables
{
// ...
public virtual IList<IRequirement> Requirements { get; set; }
}
Trying to add to that collection fails (as I expect it to). Here is why I am confused.
If I can add to the generic IList<IRequirement> in my session, why not in an object?
How is nHibernate understanding the difference between two entities with the same Id,
if they are both mapped as the same kind of object, in one scenario, and not the other?
Can someone explain to me what in the world is going on here?
The suggested approach is to use SubclassMap<T>, however the problem with that is the number of identities, and the size of the table. I am concerned about scalability and performance if multiple objects (up to about 8) are referencing identities from one table. Can someone give me some insight on this one specifically?
Take a look at the chapter Inheritance mapping in the reference documentation. In the chapter Limitations you can see what's possible with which mapping strategy.
You've chose one of the "table per concrete class" strategies, as far as I can see. You may need <one-to-many> with inverse=true or <many-to-any> to map it.
If you want to avoid this, you need to map IRequirement as a base class into a table, then it is possible to have foreign keys to that table. Doing so you turn it into a "table per class-hierarchy" or "table per subclass" mapping. This is of course not possible if another base class is already mapped. E.g. SomeKindOfObject.
Edit: some more information about <one-to-many> with inverse=true and <many-to-any>.
When you use <one-to-many>, the foreign key is actually in the requirement tables pointing back to the Item. This works well so far, NH unions all the requirement tables to find all the items in the list. Inverse is required because it forces you to have a reference from the requirement to the Item, which is used by NH to build the foreign key.
<many-to-any> is even more flexible. It stores the list in an additional link table. This table has three columns:
the foreign key to the Item,
the name of the actual requirement type (.NET type or entity name)
and the primary key of the requirement (which can't be a foreign key, because it could point to different tables).
When NH reads this table, it knows from the type information (and the corresponding requirement mapping) in which other tables the requirements are. This is how any-types work.
That it is actually a many-to-many relation shouldn't bother you, it only means that it stores the relation in an additional table which is technically able to link a requirement to more then one item.
Edit 2: freaky results:
You mapped 3 tables: IRequirement, ObjectThatImplementsRequirement, AnotherObjectThatHasRequirement. They are all completely independent. You are still on "table per concrete class with implicit polymorphism". You just added another table with containing IRequirements, which may also result in some ambiguity when NH tries to find the correct table.
Of course you get 1, 1 as result. The have independent tables and therefore independent ids which both start with 1.
The part that works: NHibernate is able to find all the objects implementing an interface in the whole database when you query for it. Try session.CreateQuery("from object") and you get the whole database.
The part that doesn't work: On the other side, you can't get an object just by id and interface or object. So session.Get<object>(1) doesn't work, because there are many objects with id 1. The same problem is with the list. And there are some more problems there, for instance the fact that with implicit polymorphism, there is no foreign key specified which points from every type implementing IRequirement to the Item.
The any types: This is where the any type mapping comes in. Any types are stored with additional type information in the database and that's done by the <many-to-any> mapping which stores the foreign key and type information in an additional table. With this additional type information NH is able to find the table where the record is stored in.
The freaky results: Consider that NH needs to find both ways, from the object to a single table and from the record to a single class. So be careful when mapping both the interface and the concrete classes independently. It could happen that NH uses one or the other table depending on which way you access the data. This may have been the cause or your freaky results.
The other solution: Using any of the other inheritance mapping strategies, you define a single table where NH can start reading and finding the type.
The Id Scope: If you are using Int32 as id, you can create 1 record each second for 68 years until you run out of ids. If this is not enough, just switch to long, you'll get ... probably more then the database is able to store in the next few thousand years...

Is it possible to have a OneToOne relation to a class hierarchy persisted using JoinedBase?

I'd like one of my entities to have a one-to-one relationship with a class hierarchy. Think of it like a Strategy pattern, where each strategy needs different parameters to be persisted. I tried using a combination of OneToOne and JoinedBase/JoinedKey, but I've come across a problem.
With this combination, the primary key of the main entity also appears as the primary key of the table representing the root class in the hierarchy, and as the primary key of the subclass:
Order --------------- TaxCalculator
([PrimaryKey]Id = 1234) ([PrimaryKey(PrimaryKeyType.Foreign)]OrderId = 1234)
^
|
|
UkTaxCalculator
([JoinedKey]UkTaxCalculatorId = 1234)
I can persist this fine, but then I can't change which subclass of TaxCalculator I have. When I do something like:
order.TaxCalculator = new OverseasTaxCalculator(order);
then try to flush, then ActiveRecord/NHibernate (understandably) gets unhappy that there are now two TaxCalculators with Id = 1234.
I can get around this by replacing the OneToOne with a HasMany/BelongsTo, and hiding the multiplicity from users of the Order object, but I'm interested to know if it's possible to do this with OneToOne.
There's a full code example on github. This code throws an exception when the second SessionScope is disposed. If you clone the project, it should run out-of-the-box.
first of all i am sorry, but i did not tried my solution. It is to late and i really need my sleep ;-). I think the only way the one-to-one could work would be a 'table-per-hierarchy'-approach using a discriminator column instead of table-per-subclass. Maybe this will enable you to morph the existing object to another subclass. An other way, something like a polymorphic delete-orphan unfortunately is not supported as you stated. So i'll guess this would be your (very) last option.
But if this fails why don't you map it as a one-to-many instead of many-to-one with a foreign key in the order table, reusing the TaxCalculators? I would imagine them as quite static.
Interesting idea though: polymorphic delete-orphan.
We do something very similar to what you are trying to do. I think it's your combination of one-to-one and the joined key that's causing the problem. Try this:
[ActiveRecord, JoinedBase]
public class TaxCalculator
{
protected int TaxCalculatorId;
[PrimaryKey]
public virtual int Id
{
get { return TaxCalculatorId; }
set { TaxCalculatorId = value; }
}
// common tax calculation fields, methods etc...
}
[ActiveRecord]
public class OverseasTaxCalculator : TaxCalculator
{
[JoinedKey]
public override int Id
{
get { return TaxCalculatorId; }
set { TaxCalculatorId = value; }
}
// overseas tax calculation specific methods, properties etc...
}