It seems like a problem with @NaturalId. I have MySQL database and User entity with natural id:
Code:
@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
...
@NotNull
@NaturalId
@Pattern(regexp = "[a-z\\d]+", message = "invalid.login.nickname")
private String name;
...
}
When I insert a new entity with JPA api NaturalIdResolutionCache throws NPE. Stacktrace:
Code:
SEVERE: Servlet.service() for servlet springServlet threw exception
java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:768)
at org.hibernate.engine.internal.NaturalIdXrefDelegate$NaturalIdResolutionCache.cache(NaturalIdXrefDelegate.java:454)
at org.hibernate.engine.internal.NaturalIdXrefDelegate.cacheNaturalIdCrossReference(NaturalIdXrefDelegate.java:92)
at org.hibernate.engine.internal.StatefulPersistenceContext$1.manageLocalNaturalIdCrossReference(StatefulPersistenceContext.java:1769)
at org.hibernate.action.internal.AbstractEntityInsertAction.handleNaturalIdPreSaveNotifications(AbstractEntityInsertAction.java:184)
at org.hibernate.action.internal.AbstractEntityInsertAction.<init>(AbstractEntityInsertAction.java:75)
at org.hibernate.action.internal.EntityIdentityInsertAction.<init>(EntityIdentityInsertAction.java:55)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:317)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:786)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:790)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:859)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
at $Proxy52.persist(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy52.persist(Unknown Source)
...
The reason of exception is that MySQL generates id value AFTER query is executed.
Please let me know if you need any additional info.
Regards,
Maksim Chemerisuk