I have the following entity which works fine during hibernate insert.
User.java
@Entity
@Table
@Inheritance(strategy = InheritanceType.JOINED)
public class User extends PersistentObject {
private static final long serialVersionUID = -1803375723276957167L;
// commenting this association allows update to work successfully.
@OneToOne(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private ContactInfo contactInfo;
private String name;
}
Then, I tried to perform update on an entity that I believe it is detached and get null pointer exception during cascadeOnUpdate.
Exception
java.lang.NullPointerException
at org.hibernate.engine.spi.EntityEntry.getLoadedValue(EntityEntry.java:274)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:236)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:132)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:361)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:335)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:239)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:724)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:716)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:712)
at com.myapp.dao.GenericHibernateDAO.save(GenericHibernateDAO.java:279)
at com.myapp.service.StaffInfoServiceImpl.storeInfo(StaffInfoServiceImpl.java:74)
at com.myapp.service.StaffInfoServiceImpl.storeInfo(StaffInfoServiceImpl.java:1)
UPDATE
ContactInfo.java
@Entity
@Table
@DynamicUpdate
public class ContactInfo implements Serializable {
private static final long serialVersionUID = 4485388013971134422L;
@Column
@Length(min = 3, max = 50)
private String currentCity;
@ManyToOne
@JoinColumn(name = "current_country_id")
private Country currentCountry;
@Column(columnDefinition = "char(10)")
private String currentPostCode;
@Column
@Length(min = 3, max = 50)
private String currentState;
@Column
@Length(min = 3, max = 50)
private String currentStreetOne;
@Column
@Length(min = 3, max = 50)
private String currentStreetThree;
@Column
@Length(min = 3, max = 50)
private String currentStreetTwo;
@Column
@Email
private String email;
@Column
@Length(max = 20)
private String fax;
@Column
@Length(max = 20)
private String homePhone;
@GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "user"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "user_id", unique = true, nullable = false)
private Long id;
@Column
@Length(max = 20)
private String mobilePhone;
@Column
@Length(max = 20)
private String officePhone;
@Column
@Length(min = 3, max = 50)
private String permanentCity;
@ManyToOne
@JoinColumn(name = "permanent_country_id")
private Country permanentCountry;
@Column(columnDefinition = "char(10)")
private String permanentPostCode;
@Column
@Length(min = 3, max = 50)
private String permanentState;
@Column
@Length(min = 3, max = 50)
private String permanentStreetOne;
@Column
@Length(min = 3, max = 50)
private String permanentStreetThree;
@Column
@Length(min = 3, max = 50)
private String permanentStreetTwo;
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private User user;
@Version
@Column(name = "version")
private Integer version = 0;
}
My question is why during insert the exception is not thrown while during update it is ? What did I miss here ?
This is bug of hibernate, that was fixed in version 4.1.7.
Temporary workaround for your version, use session.merge instead of session.saveOrUpdate.
Problem was fixed under this task
I think this error is because of the orphanRemoval = true property in the @OneToOne association.
When you update the User with null reference to ContactInfo, the hibernate might be assuming that the ContactInfo reference was set to null and then it try to remove the object that 'was there(but never existed)' because of the orphanRemoval semantic.
If my logic about this error is true, there is one bug in the hibernate. Maybe this is fixed in a newer version of hibernate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With