Java 保存时休眠一对一空外键

Java 保存时休眠一对一空外键,java,spring,hibernate,Java,Spring,Hibernate,我有一对一关系的问题-保存后,外键总是被设置为空,即使我有关联的对象。我正在使用Hibernate4.3.7.Final和Spring4.0.0.RELEASE以及MySQL5.6数据库 在我保存LawFirmProfile对象列后的情况下,参考lawFirm的lawFirm_id始终为空 实体: @Data @Entity @Table(name="usr_lawfirm") @PrimaryKeyJoinColumn(name="userId") public class LawFirm e

我有一对一关系的问题-保存后,外键总是被设置为空,即使我有关联的对象。我正在使用Hibernate4.3.7.Final和Spring4.0.0.RELEASE以及MySQL5.6数据库

在我保存LawFirmProfile对象列后的情况下,参考lawFirm的lawFirm_id始终为空

实体:

@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);
}
<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>
这里是负责保存此记录的代码:

@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);
}
<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>
休眠和Spring配置:

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

我想尽一切办法让它工作,但没有成功。

您的
律师事务所
律师事务所简介
的课堂参考应该是这样的

@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;
}
public void setLawFirm(LawFirm lawFirm) {
    this.lawFirm = lawFirm;

    if(lawFirm != null) {
        lawFirmId = lawFirm.getUserId();
    }
}
现在来上你的法律档案课。确保is有一个参数
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,setter如下:

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

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

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

然后,如评论中所述,从lf\U配置文件中删除
id
列,并将lawFirm\u id作为主键。

您对
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;
}
public void setLawFirm(LawFirm lawFirm) {
    this.lawFirm = lawFirm;

    if(lawFirm != null) {
        lawFirmId = lawFirm.getUserId();
    }
}
现在来上你的法律档案课。确保is有一个参数
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,setter如下:

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

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

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

然后,如评论中所述,从lf\U配置文件中删除
id
列,并将lawFirm\u id作为主键。

在LawFirmProfile类中,您有一个名为lawFirm\u id的参数,正确吗?我在上面的代码中看不到它,但是也许你为了简洁而删除它。我有律师事务所属性,而RealStRyID是律师事务所引用的列名。你能为这三个类显示你的DB结构吗?当然,这里是DB结构:好的,我正在输入一个希望能为你工作的ASWER。一个问题。你能修改数据库吗?lf_profile不需要它自己的唯一id列,因为它与usr_lawfirm有一个onetoone映射,所以只需使用lawfirm_id作为主键即可。在LawFirmProfile类中,您有一个名为lawfirm_id的参数,对吗?我在上面的代码中看不到它,但是也许你为了简洁而删除它。我有律师事务所属性,而RealStRyID是律师事务所引用的列名。你能为这三个类显示你的DB结构吗?当然,这里是DB结构:好的,我正在输入一个希望能为你工作的ASWER。一个问题。你能修改数据库吗?lf_profile不需要自己的唯一id列,因为它与usr_lawfirm有一个onetoone映射,所以只需使用lawfirm_id作为主键就可以了。