Java Hibernate一对多映射正在尝试将映射列更新为null

Java Hibernate一对多映射正在尝试将映射列更新为null,java,spring,hibernate,jpa,annotations,Java,Spring,Hibernate,Jpa,Annotations,我正在使用下面的映射 @Entity @Table(name = "test") public class TestOrder implements Serializable { @Id @Column(name = "orderid", updatable = false) protected Long orderId; @OneToMany(cascade = {CascadeType.ALL}) @JoinColumn(name = "order

我正在使用下面的映射

@Entity
@Table(name = "test")
public class TestOrder implements Serializable {

    @Id
    @Column(name = "orderid", updatable = false)
    protected Long orderId;

    @OneToMany(cascade = {CascadeType.ALL})
    @JoinColumn(name = "order_id_fk")
    private List<TestDetails> details;

//getters and setters
}

@Entity
@Table(name="test_details")
public class TestDetails implements Serializable {

    @Id
    //Generator
    @Column(name = "id", updatable = false, insertable = false)
    protected Long id;

    @Column(name="order_id_fk", updatable = false)
    private Long orderId;
//getters and setters
}
非常感谢您的帮助

使用Spring集成更新/插入

<int-jpa:updating-outbound-gateway entity-class="com.aaaa.TestOrder" entity-manager-factory="myEntityManagerFactory" persist-mode="MERGE">
    <int-jpa:transactional propagation="REQUIRED" transaction-manager="myTransactionManager" />
</int-jpa:updating-outbound-gateway>

我运行了您的代码,并且它工作正常(将
@GeneratedValue(strategy=GenerationType.AUTO)
添加到两个ID中时)

以下SQL的结果是什么:

[03/07/14 10:03:30]  INFO jdbc.sqlonly: insert into test (orderid) values (1) 
[03/07/14 10:03:30]  INFO jdbc.sqlonly: insert into test_details (order_id_fk, id) values (NULL, 2) 
[03/07/14 10:03:30]  INFO jdbc.sqlonly: insert into test_details (order_id_fk, id) values (NULL, 3) 
[03/07/14 10:03:30]  INFO jdbc.sqlonly: insert into test_details (order_id_fk, id) values (NULL, 4) 
[03/07/14 10:03:30]  INFO jdbc.sqlonly: update test_details set order_id_fk=1 where id=2 
[03/07/14 10:03:30]  INFO jdbc.sqlonly: update test_details set order_id_fk=1 where id=3 
[03/07/14 10:03:30]  INFO jdbc.sqlonly: update test_details set order_id_fk=1 where id=4
因此,如果您发布的代码是您编译的代码,那么TestOrder实体无法生成其ID(缺少
@GeneratedValue
注释)

如果数据库为该实体生成ID(即使用自动编号),您应该将
@GeneratedValue
设置为
IDENTITY
,让您的jpa提供商知道必须在之后重新读取插入的行。如果jpa提供程序无法重新读取id,它会将test_details order_id_fk列更新为null


PS.为什么不在TestDetails端设置多对一关系?

您需要急切地获取
TestDetails
实体的值

只需在注释中修改

@OneToMany(fetch = FetchType.EAGER, mappedBy="testOrder", cascade=CascadeType.ALL)

希望这能起作用。

您可能需要更改以下实体。就我所记得的,如果你试图设置一列的外键,这是最好的

@Entity
@Table(name="test_details")
public class TestDetails implements Serializable {

    @Id
    //Generator
    @Column(name = "id", updatable = false, insertable = false)
    protected Long id;

    @Column(name="order_id_fk", updatable = false, insertable = false)
    private TestOrder orderId;
//getters and setters
}

请粘贴代码DAO好吗?@Pracede,我正在使用spring集成来插入/更新。更新的操作在保存或更新之前是否设置了TestOrder和it属性详细信息?@Pracede,是。令人惊讶的是,它像预期的那样首先插入数据。但在此之后,它将尝试执行此更新查询where@manytone annotation和
mappedBy
?感谢您的努力。我会检查并向你汇报。关于TestDetails中的多对一,是否有必要?因为我在Hibernate中确实看到了一些循环依赖关系和问题:),这是不必要的,并且会导致您记住更新关系的双方(
testOrder.setDetails(testDetails);testDetails.setOrder(testOrder)
)。但它允许您简单地从testDetails实例导航到testOrder实例(通过
testDetails.getOrder()
)。您可能会遇到循环依赖项错误,因为双向关系端中的一个应该是反向的(这一个没有带外键的列)。通过在您的
@OneToMany
注释中添加
mappedBy
属性,可以标记反向面。我查看了大量的代码库,发现它正在从其他表
temp\u order
获取
订单id
。简言之,在
temp\u order
表中创建的第一个订单,将作为
order
表中的
id
使用
mappedBy
而不是
Join Column
。因为
TestOrder
应该是所有者,并且
TestDetails
在其模式中有外键列[Order\u id\u fk]还有一个疑问,如果我添加
mappedBy
,我必须将
TestOrder
属性添加到
TestDetails
多通
关系。是否必须像我预期的那样具有双向关系。如果使用mapped by,则hibernate将知道需要获取哪些实体值。同意。但它也需要从另一个方面进行映射[测试细节]。只是为了增加我的知识,它应该是这样的还是我最初的方法有缺陷?这里不需要加入列,因为参考模型对象,您将获得testDetails列表。只需确保在TestDetails中使用TestOrder分配了多个关系。因此,请从TestOrder中删除testDetails的JoinColumn,并将其更改为仅限oneToMany关系。我认为您必须重试:)这是完成此操作的正确方法。
@OneToMany(fetch = FetchType.EAGER, mappedBy="testOrder", cascade=CascadeType.ALL)
@Entity
@Table(name="test_details")
public class TestDetails implements Serializable {

    @Id
    //Generator
    @Column(name = "id", updatable = false, insertable = false)
    protected Long id;

    @Column(name="order_id_fk", updatable = false, insertable = false)
    private TestOrder orderId;
//getters and setters
}