JPA – 使用EclipseLink保持单向一对多关系失败

我试图坚持一个非常简单的单向一对多关系,但EclipseLink(2.3.1)失败了。

服务类(父母):

@Entity @Table(name = "tbl_service2") public class Service implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="service_id") public long serviceID; @Column(name="name") public String name; @OneToMany(cascade={CascadeType.ALL}) @JoinColumn(name="service_id", referencedColumnName="service_id") public Set parameters; } 

参数类(子):
(当然在数据库中有“service_id”外键字段,它没有在类中表示,因为它是单向关系)。

 @Entity @Table(name = "tbl_service_parameters2") public class Parameter implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="param_id") public long parameterID; @Column(name="name") public String name; } 

这是实体持久性的代码:

  Service service = new Service(); service.parameters = new HashSet(); service.name = "test"; Parameter param = new Parameter(); param.name = "test"; service.parameters.add(param); em.persist(service); em.flush(); 

我得到这个例外:

 Internal Exception: java.sql.SQLException: Field 'service_id' doesn't have a default value Error Code: 1364 Call: INSERT INTO tbl_service_parameters2 (name) VALUES (?) bind => [test] 

编辑:由于数据的性质,数据库字段service_id具有(并且应该具有)非空约束。

这是一个错误还是代码中的错误?

尝试删除Parameter表的service_id字段上的not null约束。 Eclipselink将在单独的语句中更新单向1:m连接列的外键,因此您需要禁用或延迟约束检查。 使其双向将允许使用其余参数数据更新fp字段。

@JoinColumn上使用nullable = false

 @JoinColumn(name = "service_id", nullable = false) 
 By default nullable is true on @JoinColumn, while persisting the data in one to many relationship, we need to make nullable as false to avoid data voliation exceptions that occurs at run-time 

您可以更改hibernate版本<4.0的持久性,并且您的代码将运行良好。“嗯”在引用中“仅用于一对多关系保存/持久父级,不通过单独任务保存/保存子级集合”

通过使用可延迟的外键,我能够在Oracle中使用它。

例:

 ALTER TABLE my_table ADD CONSTRAINT my_constraint_name FOREIGN KEY (my_table_column) REFERENCES foreign_key_table (foreign_key_table_column) DEFERRABLE INITIALLY DEFERRED 

我发现,在这种情况下,外键填写在一个单独的声明中。 在我的示例中,我使用带有customer_id Address实体作为外键。

 2014-07-08T20:51:12.752+0300|FINE: INSERT INTO ADDRESS (address_id, street, city, region) VALUES (?, ?, ?, ?) bind => [10, foo, foo, foo] 2014-07-08T20:51:12.753+0300|FINEST: Execute query InsertObjectQuery(ua.test.customer.Address@28cef39d) 2014-07-08T20:51:12.757+0300|FINEST: Execute query DataModifyQuery(sql="UPDATE ADDRESS SET customer_id = ? WHERE (address_id = ?)") 2014-07-08T20:51:12.757+0300|FINE: UPDATE ADDRESS SET customer_id = ? WHERE (address_id = ?) bind => [151, 10] 

因此,将@JoinColumnnullable=true导致错误。

或者,您可以使用@OneToMany (..., orphanRemoval = true, ...)