27

我试图坚持一个非常简单的单向一对多关系,但 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具有(并且应该具有)非空约束。

这是一个错误还是代码中有问题?

4

6 回答 6

38

使用nullable = false, 在@JoinColumn:

@JoinColumn(name = "service_id", nullable = false)
于 2012-12-26T20:52:46.827 回答
14

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

于 2012-10-06T19:42:31.503 回答
1

通过使用可延迟的外键,我能够让它在 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
于 2013-11-20T16:30:57.663 回答
1

您可以将您的持久性更改为休眠版本<4.0,并且您的代码将运行良好。“好吧”参考“仅用于一对多关系保存/持久父,而不是通过单独的任务保存/持久子的集合”

于 2012-11-20T16:41:18.053 回答
1

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

于 2018-07-06T14:13:35.823 回答
0

我发现,在这种情况下,外键填写在单独的语句中。在我的示例中,我使用Address实体customer_id作为外键。

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]

因此,拥有@JoinColumnwithnullable=true会导致错误。

作为替代方案,您可以使用@OneToMany (..., orphanRemoval = true, ...).

于 2014-07-08T18:02:27.973 回答