This is a known issue with ORM. Here I outline the solutions I know about and give a few pointers.
1 Surrogate/primary key: auto-generated
As you mentionned, if the object has not been saved, this doesn't work.
2 Surrogate/primary key: assigned value
You can decide to assign the value of the PK in the code, this way the object has always an ID and can be used for comparison. See Don't let hibernate steal your identity.
3 Natural key
If the object has another natural key, other than the primary key, you can use this one. This would be the case for a client entity, which has a numeric primary key and a string client number. The client number identifies the client in the real world and is a natural key which won't change.
4 Object values
Using the object values for equality is possible. But is has other shortcomings has you mentioned. This can be problematic if the values changes and the object is in a collection. For instance, if you have a Set
with two objects that were different at first, but then you change the values while they are reference in the set so that they become equal. Then you break the contract of the Set
. See Hibernate equals and hashcode.
5 Mixed: value + autogenerate primary/surrogate keys
If the objects to compare have an ID already, use it. Otherwise, use the object values for comparison.
All have some pros and cons. IMHO, the best is 3, if it is possible with your domain model. Otherwise, I've used 5 and it worked, though there are still some trap when using collections. I never used 2 but that sounds also a sensible solution, if you find a way to generate the PK in the code. Maybe other people have pointers for this one.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…