Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

ManyToOne Composite Key with Transient Field

 
Yatin Mistry
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All, I need some help please.

I want to map the tables below. The problem, is that when i create the schema from hibernate. The product_table is created with "localLanguage", and "localeVariant" colums, which should not be there.

When i get the region for a product, i want the "localLanguage" and "localeVariant" values to be picked up from the transient variables declared in the ProductBo Object.

i.e. i should be able to do the following, and the correct region should be returned.



How do i do this?

(I understand that this is not good database design.)

One Product has One Region. A region can belong to many products. Each region, could have many values, depending on the lanaguage and variant values.

product_table
*product_id
region_id

region_table
*region_id
*locale_lanaugage
*locale_variant
value

(* represents the Primary Key or Composite Primary key in the region_table)

The Hibernate mappings are as follows:

Product Object
 
Mike Keith
author
Ranch Hand
Posts: 304
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Yatin,

First of all, those annotations are not "Hibernate mappings", they are the JPA mappings. This is a big difference, because using JPA mappings means that you are using a standard not proprietary mappings.

The problem is that it is not defined to use annotations on both fields and properties. You are using property access and getting burned by it because your property methods are getting defaulted to be stored in the primary table of the entity. I would recommend that you take the mapping annotations off of your get methods and put them on your fields. Then your existing @Transient annotations will be recognized and the additional columns will not be created.
 
Yatin Mistry
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Mike,
Thank you for your reply, it is very much appreciated.

Mike, All the annotations i have used are on my fields, and there are non on my properties(i.e. getter methods). I dont understand why you think i am using annotations on properties.

In my ProductBo I have two transient fields, which are not persisted to the database. But they store the locale (language and variant) values. These values are used to get hold of the correct region, based on the language and variant.



i.e. in pseudo SQL the following should happen. Where "en" comes from the localeLanaguge field in the ProductBo, and "cm" comes from the localeVariant field in the ProductBo.


SELECT region
FROM product_table prod, region_table reg
WHERE prod.region_id = reg.region_id AND
region.locale_lanaguage = "en" AND
region.locale_variant = "cm"


I have tried to do that in the following join, but unsuccessfully. This code, thinks that localeLanaguage and localeVariant are fields in the product_table table. And when i create this database (using the Schema Export feature of hibernate), the product_table, has two extra fields added (localeLanugage and localeVariant) which should not be present, as they are defined as @Transient.



I think I need a line simlar to But where is not presumed to be a physical colum in the database, but instead a field in the ProductBo object.

Thanks again for your help
 
Rodrigo Lopes
Ranch Hand
Posts: 119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If the Region primary key is defined by the 'triple' [region_id, locale_language, locale_variant], then the product MUST have these 3 fields as FKs.
Also, if you define local_language and local_variant as join columns, then they must exist in the Product table.
[ June 04, 2008: Message edited by: Rodrigo Lopes ]
 
Yatin Mistry
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rodrigo, thanks for your reply,

I want my annotations to be able to do something similar to the SQL statement i posted. Is there a way to reference a transient fields value, in the hibernate code.

So where @XXXXX is an annotation probably not @JoinColumn and where value would be picked up from
 
Mike Keith
author
Ranch Hand
Posts: 304
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike, All the annotations i have used are on my fields, and there are non on my properties(i.e. getter methods). I dont understand why you think i am using annotations on properties.

Doh. The common cause of what you encountered is mixing property and field access so I apparently didn't read your code very closely and went on to talk about what I expected you had. Very sorry about that.

After actually *looking* at your code ;-) your region has a composite primary key, so like Rodrigo said, you do need to have the JoinColumns there, and the JPA provider does need to generate the foreign key columns in PRODUCT_TABLE. Note that the columns being generated should be foreign keys (integer) not strings, so the columns are not actually being generated for your localeLanguage and localeVariant fields in ProductBo.

The SQL that you listed above is not really the way to look at it. If you really do have a Region associated with a Product then there is an actual Region PK (made up of the three PK fields) stored in the PRODUCT_TABLE, so when you created the ProductBo instance then it has its associated Region and you need only access the region to get the values of the language and the variant. In this case, then I wouldn't even declare any Transient fields for these two things in ProductBo, I would just define some get methods that get the data from the related Region object (where it is already stored). For example:

public String getLocaleLanguage() {
return this.getRegion().getLocaleLanguage();
}

Hope this clears things up, and sorry about the brain cramp.

-Mike
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic