2013-06-17 3 views
1

У меня есть следующий объект, который отлично работает во время спящего режима.Обновление каскада Hibernate дает нулевой указатель

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; 
} 

Затем я попытался выполнить обновление на объект, который я считаю, что отрывается и получить исключения нулевого указателя при cascadeOnUpdate.

Исключение

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; 
} 

Мой вопрос, почему во время вставки исключение не выбрасывается, а при обновлении это? Что я здесь пропустил?

+0

Пожалуйста, покажите нам класс 'ContactInfo' а – Manuel

+0

Добавлено' ContactInfo' по запросу. Спасибо – abiieez

+0

Есть ли что-нибудь релевантное в 'PersistentObject'? – Manuel

ответ

3

Это спящего режима, которое было исправлено в версии 4.1.7.
Временное обходное решение для вашей версии, используйте session.merge вместо session.saveOrUpdate.

Проблема была установлена ​​в соответствии с настоящим task

4

Я думаю, что эта ошибка из-за orphanRemoval = true собственности в ассоциации @OneToOne.

При обновлении User с null ссылку на ContactInfo, то спящий режим может быть при условии, что ContactInfo ссылка была установлена ​​на null и затем попытаться удалить объект, который «был там (но никогда не существовало)» из-за семантика orphanRemoval.

Если моя логика об этой ошибке верна, в спящем режиме есть одна ошибка. Возможно, это исправлено в более новой версии спящего режима.

Смежные вопросы