aspose file tools*
The moose likes Object Relational Mapping and the fly likes Retrieve record based on unique field Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Retrieve record based on unique field" Watch "Retrieve record based on unique field" New topic
Author

Retrieve record based on unique field

Steve Garing
Greenhorn

Joined: Oct 02, 2012
Posts: 2

Hi all,

First post on coderanch for me! I am very new (say about 8hrs) to Hibernate so I am hoping I can explain this properly.

I have a situation where I need to record the countries a user has logged in from. This information is read in from an xml file and persisted to the database. It is possible that users can have a history of logging in from many countries if they travel. When I read in the country for each user I only have the name of the country and not the primary key that the country is associated with in the DB. So I am currently creating a Country object, setting the name (without and id) and then adding that object to the countries list in the User object.

To implement this I have 3 tables, User, Country (purely a reference table) and User_Country (to handle the many-to-many situation). In my User @Entity class I am using the @JoinTable on my getCountries() method to tell hibernate about the many-to-many relationship. When I persist the User object it it is successfully persisting the User and User_Country entries but it is also creating new duplicate entries in the Country table and using these entries as the country_id in the User_Countries table. I could mark the countryName field as unique in the @Column but I suspect that won't fix my problem as it will attempt to insert a duplicate and fail.

I have 3 thoughts as to why this is happening:
1. Because I am adding countries to the User without and ID, hibernate thinks these are new countries and adding them to the database before finally updating the User_Countries table. Should I be looking up the Country by the country name and adding the complete object to the User class (can you look up record in Hibernate purely based on a unique field??)
2. I have done something wrong with the @JoinTable and I am missing something that tells Hibernate not to update the Countries table and to only update the User and User_Countries table
3. I am way off and it's another problem all together

Is anyone able to help out? Hopefully that makes sense. Thanks in advance!!

My cut down User class and Country class Code is below.

User.java


Country.java
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1649
    
    7

If I understand you correctly you are on the right track with what you said in your first point. Objects are uniquely defined in the persistence context by their persistent identifier (the one you annotate with @Id). If you are adding countries with a null id then it will see it as a new entity and persist it. If you were to put a unique constraint on country name you are correct that it will throw a constraint violation. You have 2 options.

1. Issue a query to find the country by name and add the result of that query to your user.
2. Since the country table is purely a look-up table don't set a generation strategy on the country object and use its name as the @Id. Of course if you have other information about the country stored, you will still have to do a findById to get the fully populated country object but you can then use the name as the id.

You can set the insertable and updateable attributes to false on your join column if this table is pre-populated and you don't want the application to be able to change them.


[How To Ask Questions][Read before you PM me]
Steve Garing
Greenhorn

Joined: Oct 02, 2012
Posts: 2

Bill Gorder wrote:If I understand you correctly you are on the right track with what you said in your first point. Objects are uniquely defined in the persistence context by their persistent identifier (the one you annotate with @Id). If you are adding countries with a null id then it will see it as a new entity and persist it. If you were to put a unique constraint on country name you are correct that it will throw a constraint violation. You have 2 options.

1. Issue a query to find the country by name and add the result of that query to your user.
2. Since the country table is purely a look-up table don't set a generation strategy on the country object and use its name as the @Id. Of course if you have other information about the country stored, you will still have to do a findById to get the fully populated country object but you can then use the name as the id.

You can set the insertable and updateable attributes to false on your join column if this table is pre-populated and you don't want the application to be able to change them.



Thanks Bill, you did understand correctly. My apologies if the explanation was a little confusing. I was hoping not to have to do an initial call to the database to get the lookup record but it looks like I may need too. I may just do a full lookup of the countries and put them into a set rather than looking up each country by the name as I encounter each entry in the file. This way it should be one call for <200 records compared to hundreds to thousands of calls for single countries. Thanks for confirming what I thought.
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1649
    
    7

Yup you could load the set once if it never changes and store it as a class member. However once you start getting more comfortable with Hibernate this kind of thing is a good candidate for a second level cache. That way when you request that data it gets it from your cache rather than going to the database.

If you are interested in caching we had a discussion on it awhile back here:
http://www.coderanch.com/t/590423/ORM/databases/Caching-Technique-Hibernate#2689280

Good luck!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Retrieve record based on unique field