2016-01-07 85 views
1

我有一對一的關係問題 - 保存外鍵後總是被設置爲空即使我有關聯的對象。我在Spring 4.0.0.RELEASE和MySql 5.6數據庫中使用Hibernate 4.3.7.Final。休眠一對一空外鍵,同時保存

在我保存LawFirmProfile對象列lawFirm_id後,參照LawFirm始終爲null。

實體:

@Data 
@Entity 
@Table(name="usr_lawfirm") 
@PrimaryKeyJoinColumn(name="userId") 
public class LawFirm extends User implements Serializable{ 

    ... 

    @OneToOne(mappedBy = "lawFirm") 
    private LawFirmProfile lawFirmProfile = new LawFirmProfile(); 


    @Override 
    public boolean equals(Object obj){ 
     return super.equals(obj); 
    } 

    @Override 
    public int hashCode() { 
     return super.hashCode(); 
    } 

} 


@Data 
@Entity 
@Table(name="lf_profile") 
@EqualsAndHashCode(of = {"id"}) 
public class LawFirmProfile implements Serializable{ 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    private Integer id; 

    ... 

    @OneToOne 
    @JoinColumn(name = "lawFirm_id") 
    private LawFirm lawFirm; 

} 

@Data 
@Entity 
@Table(name = "usr_user") 
@Inheritance(strategy = InheritanceType.JOINED) 
@EqualsAndHashCode(of = {"email"}) 
public class User implements Serializable { 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(unique = true, nullable = false) 
    private Integer userId; 

    @Column(unique = true) 
    private String email; 

    ... 
} 

這裏是負責保存該記錄代碼:

@Override 
@Transactional 
public void saveProfile(LawFirm lawFirm){ 
    LawFirmProfile profile = lawFirm.getLawFirmProfile(); 
    userDao.update(lawFirm); 
    profile.setLawFirm(lawFirm); 
    lawFirmProfileDao.saveOrUpdate(profile); 
} 

Hibernate和Spring配置:

<tx:annotation-driven transaction-manager="transactionManager"/> 

<bean 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="location"> 
     <value>system.properties</value> 
    </property> 
</bean> 

<bean id="dataSource" 
     class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
    <property name="driverClass" value="${jdbc.driverClassName}" /> 
    <property name="jdbcUrl" value="${jdbc.url}" /> 
    <property name="user" value="${jdbc.username}" /> 
    <property name="password" value="${jdbc.password}" /> 

    <property name="minPoolSize" value="${c3p0.minPoolSize}" /> 
    <property name="maxPoolSize" value="${c3p0.maxPoolSize}" /> 
    <property name="maxIdleTime" value="${c3p0.maxIdleTime}" /> 
    <property name="maxStatements" value ="${c3p0.maxStatements}" /> 

</bean> 

<!-- Hibernate session factory --> 
<bean id="sessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource"> 
     <ref bean="dataSource"/> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
      <prop key="hibernate.show_sql">true</prop> 
      <prop key="hibernate.hbm2ddl.auto">update</prop> 
      <prop key="hibernate.validator.apply_to_ddl">false</prop> 
      <prop key="hibernate.validator.autoregister_listeners">false</prop> 
      <prop key="javax.persistence.validation.mode">none</prop> 
     </props> 
    </property> 
    <property name="packagesToScan" value="com.test." /> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

Dao也是Spring bean,註釋爲@Transactional。

在保存期間,我從C3p0得到以下錯誤。然而,LawFirmProfile記錄保存在數據庫中,但是引用LawFirm爲空。

2016-01-07 13:25:26,084 Participating in existing transaction 
2016-01-07 13:25:26,095 Adding transactional method 'saveOrUpdate' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
2016-01-07 13:25:26,096 Returning cached instance of singleton bean 'transactionManager' 
2016-01-07 13:25:26,096 Found thread-bound Session [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com.efsf.gateone.user.model.LawFirm#55]],collectionKeys=[CollectionKey[com.efsf.gateone.user.model.User.sendMessages#55], CollectionKey[com.efsf.gateone.user.model.User.payments#55], CollectionKey[com.efsf.gateone.user.model.LawFirm.invitations#55], CollectionKey[com.efsf.gateone.user.model.User.receivedMessages#55], CollectionKey[com.efsf.gateone.user.model.User.attachments#55], CollectionKey[com.efsf.gateone.user.model.LawFirm.legalCases#55]]];ActionQueue[[email protected] [email protected] [email protected] [email protected] [email protected]aba1 [email protected]a2 [email protected]7c [email protected]2a03 unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
2016-01-07 13:25:26,096 Participating in existing transaction 
Hibernate: insert into lf_profile (city, postCode, street, krsNumber, name, nip, regon, email, phone, website, description, latitude, longitude, lawFirm_id, lawFirmType, lawyerNumber, pricePerHour, solicitorNumber, specialization) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 
2016-01-07 13:25:26,126 [email protected]: Adding task to queue -- [email protected]e308448 
2016-01-07 13:25:26,127 cxnStmtMgr.statementSet([email protected]).size(): 7 
2016-01-07 13:25:26,127 checkoutStatement: com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 7; checked out: 1; num connections: 1; num keys: 7 
2016-01-07 13:25:26,142 checkinStatement(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 7; checked out: 0; num connections: 1; num keys: 7 
2016-01-07 13:25:26,142 Initiating transaction commit 
2016-01-07 13:25:26,143 Committing Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com.efsf.gateone.user.model.LawFirm#55], EntityKey[com.efsf.gateone.lawfirm.model.LawFirmProfile#68]],collectionKeys=[CollectionKey[com.efsf.gateone.user.model.User.sendMessages#55], CollectionKey[com.efsf.gateone.user.model.User.payments#55], CollectionKey[com.efsf.gateone.user.model.LawFirm.invitations#55], CollectionKey[com.efsf.gateone.user.model.User.receivedMessages#55], CollectionKey[com.efsf.gateone.user.model.User.attachments#55], CollectionKey[com.efsf.gateone.user.model.LawFirm.legalCases#55]]];ActionQueue[[email protected] [email protected] [email protected] [email protected] [email protected]aba1 [email protected]a2 [email protected]7c [email protected]2a03 unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 
Hibernate: update usr_user set email=?, lastLogin=?, login=?, name=?, password=?, phone=?, premiumUntil=?, status=?, surname=? where userId=? 
2016-01-07 13:25:26,145 com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache ----> CACHE HIT 
2016-01-07 13:25:26,145 checkoutStatement: com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 7; checked out: 1; num connections: 1; num keys: 7 
2016-01-07 13:25:26,147 checkinStatement(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 7; checked out: 0; num connections: 1; num keys: 7 
2016-01-07 13:25:26,147 Converting Throwable to SQLException... 
java.lang.NullPointerException 
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.maybeDirtyTransaction(NewProxyPreparedStatement.java:2520) 
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.getMaxRows(NewProxyPreparedStatement.java:1403) 
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.close(JdbcCoordinatorImpl.java:530) 
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.release(JdbcCoordinatorImpl.java:407) 
at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.releaseStatements(AbstractBatchImpl.java:173) 
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:76) 
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3281) 
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3183) 
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3525) 
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:158) 
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:453) 

我盡一切努力使它工作,但沒有成功。

+0

在您的LawFirmProfile類中,您有一個名爲lawFirm_id的參數是否正確?我沒有在上面的代碼中看到它,但是爲了簡潔起見,您可能會刪除它嗎? – DavidR

+0

我有lawFirm屬性,而lawFirm_id是LawFirm參考的列名稱。 – michalo

+0

你可以爲這三個類顯示你的數據庫結構嗎? – DavidR

回答

0

LawFirm類參考LawFirmProfile應該是這樣的

@OneToOne(cascade = {CascadeType.ALL}) // The cascade part is probably optional 
@PrimaryKeyJoinColumn 
private LawFirmProfile lawFirmProfile; 

此外,當您LawFirm類ID獲取更新,一定要同時更新LawFirmProfile類。它應該看起來像這樣:

public void setUserId(int userId) { 
    if(LawFirmProfile != null) { 
     LawFirmProfile.setLawFirmId(userId); 
    } 

    this.userId = userId; 
} 

現在爲您的LawFirmProfile類。確保是有一個參數lawFirmId

@Column(name="lawFirm_id") 
@Id 
private int lawFirmId; 

... lawFirmId getter and setter.... 

還要確保你LawFirmProfile類有一個參考LawFirm

@MapsId 
@OneToOne 
@JoinColumn(name="lawFirmId") 
private LawFirm lawFirm; 

隨着getter和setter,與二傳是這樣的:

public void setLawFirm(LawFirm lawFirm) { 
    this.lawFirm = lawFirm; 

    if(lawFirm != null) { 
     lawFirmId = lawFirm.getUserId(); 
    } 
} 

然後作爲在評論中討論刪除lf_profile中的id列,並將lawFirm_id作爲主鍵。

+0

這個工作適合你嗎? – DavidR