Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3369
  • Last Modified:

Using @IdClass with @GeneratedValue

I am using EJB3 persistence, JBoss, MySql.  I am able to have an entity with one primary key marked with @Id where this key is an autogenerated field with the annotation @GeneratedValue(strategy=GenerationType.AUTO).  The table is created with the primary key and when persisting objects, I see the id field being incremented.

Everything works fine until I started creating entites that have composite primary keys using @IdClass where one of those keys have @GeneratedValue(strategy=GenerationType.AUTO).  I can see that the table gets created with the correct primary key.  The problem is that the primary key field that has the @GeneratedValue attribute is not being incremented; it is always 0.

I have tried different combinations of putting the @Id and @GeneratedValue attributes on the fields and getters of the entity and the primary key class but nothing works.
0
leobaz2
Asked:
leobaz2
  • 3
  • 2
1 Solution
 
Mr_ItCommented:
What is the use of a composite PK if you want to auto-generate one of the values? Isn't a single ID property unique enough to identify the entity? I really don't understand why you would like to have a composite PK if one of its properties is uniquely generated anyway. For me it makes no sense to have something like this.

Anyway, you simply cannot put @Id annotations in classes other than an entity, because it makes no sense.  The specs say:

'The Id annotation specifies the primary key property or field of an entity. The Id annotation may be applied in an entity or mapped superclass.'

It's normal that it will be ignored in the non-entity class. That's why it's always 0...

0
 
Mr_ItCommented:
Anyway, I understand that you might expect it to work with the IdClass thing, because the specs are unclear about this:

'The GeneratedValue annotation may be applied to a primary key property or
field of an entity or mapped superclass in conjunction with the Id annotation.'

If you have a composite PK, can we refer to one of the properties annotated with @Id as a primary key property? It's only a partial primary key property, not the primary key property itself. They should go into more detail about this...

Still, I don't see the purpose of having a composite key with one of the values unique. Maybe you are coding for an existing database?

Maybe vendor specific annotations can do the trick. I never came across a use case for this.

Good luck ;-)

0
 
leobaz2Author Commented:
I am going to have multiple clients sharing the same database but not the same data.  I originally had one primary key for every table that was auto generated.  I wanted to change it so that each primary key was composite on the auto generated column and the "client id".  This way, it would be impossible for a client to view another client's data.  Also, when I do a find I pass the client id along with the auto generate key which I liked.  

However, since I can't use composite primary keys with an auto generated field, I am doing a find on the auto generated field and then just verifying that the client id from the persisted object equals the logged on user's client id.
0
 
Mr_ItCommented:
I think that it's even a better design, because in my opinion, a PK should never contain any logic.

Instead of checking the client ID after retrieval, you could use a Query object and put both the PK and the client ID in the WHERE clause and call the getSingleResult() method on it. Unless you want to treat 'no result' or 'result for other client' differently, of course.

Is it possible that the same client can have multiple logins (for example different roles) in the future that have access to the same data? If yes, beware that there will be multiple user id's for just one client id. You could already take that into account in your design.
0
 
leobaz2Author Commented:
I actually agree with you that primary keys should not have business logic even though the logic is minimal in this case.  I'll change my logic to use a where clause.

Thanks for your help.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now