This was a deliberate decision. I understand that testing might get more complicated, but you really shouldn’t rely on fixed id values if you have a generator. This can lead to lot’s of other problems.
I think if you’re using Quarkus, Spring or other containers, you should be able to create a class like this and mark it as a bean to make this work:
public class SequenceOrAssignedGenerator extends SequenceStyleGenerator {
@Override
public Object generate(SharedSessionContractImplementor session, Object owner) throws HibernateException {
final Long id;
if ( owner instanceof MyEntity ) {
id = ( (MyEntity) owner ).getId();
}
else {
id = null;
}
return id != null ? id : super.generate( session, owner );
}
@Override
public boolean allowAssignedIdentifiers() {
return true;
}
}
Please let us know if it does. Maybe you can even contribute a section in the migration guide for ORM 6.6 that explains this “workaround”?
Sure. We understand this. But we have some legacy code in the older version of our application and we don’t want to invest so much in that direction.
Please let us know if it does
Thanks! This magic property works for us.
We already had a custom IdGenerator with the logic that you have shared in the overridden generate method but without allowAssignedIdentifiers property it did not work.
Maybe you can even contribute a section in the migration guide for ORM 6.6 that explains this “workaround”?
Doesn’t work in spring as you claim. Adding @Component to this doesn’t do squat.
Don’t change this part of hibernate every few versions. Every time this hits us, since you never bother to document such core changes.
This was a deliberate decision.
With which, you f****d over 100’s of projects. You knew this would cause issues, since you said this was deliberate. So you knew this. And yet, this isn’t documented in the migration guide.
Do I really need to throw up the debugger again to reverse engineer how this works, so I can override the SequenceStyleGenerator? I’m so fed up with this. Every damn few versions this part get’s broken without documenting it.
You should sometimes listen to Linus Torvalds. We don’t break user-space.
Why. You knew you would break test setups. If at least, your suggested way worked, but the generator doesn’t get triggered.
I would suggest you adapt your tone a bit unless you want to be blocked.
In case you didn’t see this when you typed the URL or looked at the logos of this forum, this is a Hibernate ORM forum, not a Spring forum. Maintainers of Hibernate projects don’t develop Spring or decide to what version it updates to, so the suggestions we give for Spring here are a best effort.
We have tests that show replacing the generator works fine and the OP even accepted the answer as solution, so maybe the problem is your setup.
If you think that there is a bug when declaring it as a bean, please try to create a reproducer with our test case template and if you are able to reproduce the issue, create a bug ticket in our issue tracker and attach that reproducer.
This is an open source project, so if you think this is important to mention, the please go ahead and propose a PR to mention it.
The thing is, this was never documented to work. It just worked by coincidence. We acknowledged that the behavior is useful for tests, which is why we added this allowAssignedIdentifiers method through an improvement ticket so you can override the behavior and even wrote about it in the ORM 6.5 release announcement. Since it is dangerous to use in production, this is not enabled by default and requires explicit code changes.
I agree this is an ok decision to make. We just stumbled upon the actual exception - it feels very misleading to me that this is an Locking Exception because its plainly not. This exception is deliberately thrown because the id is expected to be generated by the DB but is already set on a detached entity. I would suggest there should be an explicit exception for this case (something along the lines of “GeneratedIdAlreadySetException”) with an explicit message for this case. We went on a wild hunt because we assumed there was some wild things going on regarding transaction etc.
To be fair, Hibernate ORM has no way of knowing what scenario this is. It could just as well be a detached entity that was already removed by a concurrent transaction.
Is the exception actually telling the thruth in the scenario you are mentioning? It would be not my first guess if I see an “OptimistLockException” in either of the 2 cases.
I feel like both scenarios would profit from a more telling exception and/or message.
Just for completeness:
Our scenario is actually that we map Entities into domain objects and vice versa, so the entity is not managed when getting updated, but the id is obviously set
I don’t know what kind of message you think would be more helpful in this scenario. If you merge an entity object that has its id field set, which is also marked as generated, then Hibernate ORM must assume that this object exists and hence throw an error when a find/update fails. This is actually mentioned in the JPA spec as pointed out in the migration guide. Clearly, if the row was removed in the meantime, this is an optimistic lock exception.
I see, thanks for the explanation
IMO, this change actually introduced a second error case, but the exception only mentions one. This “new” error is not a database integrity error, its rather a configuration issue (assuming the code is valid). A hint of any form would be appreciated, especially considering it worked before (which I agree was wrong).
I see that Hbernate cannot differentiate between the two scenarios, but why not tell the progammer exactly that?
Again, we’re open to improvement suggestions. Please propose a PR.
It is a programmer error though to set the id value of an entity when it is marked as @GeneratedValue, unless you know a row for that object should exist.