当前位置: 首页 > 知识库问答 >
问题:

在保存时Hibernate一对一空外键

司空坚
2023-03-14

我有一对一关系的问题-保存后,外键总是被设置为空,即使我有关联的对象。我正在使用Hibernate4.3。7.最终版本为Spring 4.0。0.0版本和MySql 5.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);
}

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>

道也是Spring豆,方法注释为@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[insertions=org.hibernate.engine.spi.ExecutableList@6350cb30 updates=org.hibernate.engine.spi.ExecutableList@4d4bef40 deletions=org.hibernate.engine.spi.ExecutableList@34487a65 orphanRemovals=org.hibernate.engine.spi.ExecutableList@25b97b4 collectionCreations=org.hibernate.engine.spi.ExecutableList@4b44aba1 collectionRemovals=org.hibernate.engine.spi.ExecutableList@95ffda2 collectionUpdates=org.hibernate.engine.spi.ExecutableList@7d049b7c collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@397c2a03 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 com.mchange.v2.async.ThreadPoolAsynchronousRunner@6db73230: Adding task to queue -- com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StmtAcquireTask@7e308448
2016-01-07 13:25:26,127 cxnStmtMgr.statementSet( com.mysql.jdbc.JDBC4Connection@40a126ad ).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[insertions=org.hibernate.engine.spi.ExecutableList@6350cb30 updates=org.hibernate.engine.spi.ExecutableList@4d4bef40 deletions=org.hibernate.engine.spi.ExecutableList@34487a65 orphanRemovals=org.hibernate.engine.spi.ExecutableList@25b97b4 collectionCreations=org.hibernate.engine.spi.ExecutableList@4b44aba1 collectionRemovals=org.hibernate.engine.spi.ExecutableList@95ffda2 collectionUpdates=org.hibernate.engine.spi.ExecutableList@7d049b7c collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@397c2a03 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)

我尽一切努力使它工作,但没有成功。

共有1个答案

韦志新
2023-03-14

您对LawFirmProfile的LawFirm类引用应该如下所示

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

现在来上你的法律档案课。确保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 setLawFirm(LawFirm lawFirm) {
    this.lawFirm = lawFirm;

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

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

 类似资料:
  • 我有一个单向的一对多关系。一方是父母,多方是孩子。对于一个父母,可以有很多孩子。但是对于一个孩子来说,只有一个父母。在Java方面,关系是单向的,我需要访问父母的孩子,但是我不想为孩子存储父母。所以这些是对象: 起源: 孩子: 这是一段代码,用于创建一个子项、一个具有该子项的父项,然后保存父项: 然后,当我运行代码时,出现了一个错误,因为Hibernate在插入它时没有在CHILD上设置PAREN

  • 想要保存一个一对一的主值,如下所示。有一个address类,它包含一个city类一对一。但是city是我的主值,当我保存地址时我不想更新它。只需要从UI的下拉菜单中选择city并将对象设置为原来的地址并保存地址。但是当保存时getting below错误。 org.hibernate.transientPropertyValueException:对象引用了一个未保存的瞬态实例-在刷新之前保存瞬态

  • 问题内容: 我在个人课程和汽车课程之间有一对多的关系。一个人可以拥有许多汽车,反之亦然。我正在使用Restful API发布数据。我的注释和Get服务运行正常,但是我的后服务在每次尝试插入新数据时都抛出“ 。子表插入为” 。 这是我的代码的一部分。 人.java 汽车.java 我的服务等级: 问题答案: 此注释: 有两个后果: 暗示这是关系的拥有方。这意味着,每当要在和之间建立关系时, 都需要通

  • 问题内容: 我在父方使用批注具有一对一关系。现在,我想自己保存子实体。 例如,我有和作为孩子的实体,我需要保存(父的id属性设置为之后的课程)。但是,当使用这种安排时,我在下面列出了一个例外… 为什么hibernate不允许这样做的任何想法?更清楚地说,我的代码如下… ParentEntity: ChildEntity: 我尝试保存的方式是… 关于如何尝试保存子实体,任何指针将不胜感激。 问题答案

  • 问题内容: 我正在尝试使我的@OneToMany和@ManyToOne关系正确。 第1类: 第2类: 当我加载或保存新记录时,这种关系似乎运行良好: 但是,当我尝试更新该记录时,它将尝试将IdeaProfileId设置为null: 当我调试时,我可以看到IdeaProfileId确实在音高对象上设置了… 仅供参考,我不是直接更新从数据库加载的原始对象。这些域映射到UI更新的Model类。因此,在保

  • 问题内容: 我有两个非常简单的对象,并且一个对象应在一组“一对多”关系中包含另一个对象。对象已正确插入数据库中,但“子项”表中的外键始终为“ null”。 我不知道为什么: 这是测试对象,它将子对象保持在其集合中: 这是子对象,它包含指向“ TestObj”的反向链接: 我使用以下代码来持久化此对象: 有人可以解释一下为什么会这样吗? 问题答案: 这很简单:您永远不会初始化中的字段(应将其命名为C