繁体   English   中英

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

[英]JPA - Persisting a Unidirectional One to Many relationship fails with 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<Parameter> 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<Parameter>();
    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具有(并且应该具有)非空约束。

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

@JoinColumn上使用nullable = false

@JoinColumn(name = "service_id", nullable = false)

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

您可以更改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, ...)

默认情况下,在@JoinColumn上nullable为true,在将数据保持为一对多关系时,我们需要将nullable设为false,以避免在运行时发生的数据冲突异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM