无法使@ManyToOne关系成为可空

vca*_*tin 17 nullable many-to-one jpa-2.0 postgresql-9.1 jboss7.x

我有一个多对一的关系,我想要可以为空:

@ManyToOne(optional = true)
@JoinColumn(name = "customer_id", nullable = true)
private Customer customer;
Run Code Online (Sandbox Code Playgroud)

不幸的是,JPA将我的数据库中的列设置为NOT NULL.有谁能解释一下?有没有办法让它发挥作用?请注意,我使用JBoss 7,JPA 2.0和Hibernate作为持久性提供程序和PostgreSQL 9.1数据库.

编辑:

我找到了问题的原因.显然,这是由于我在引用实体中定义主键的方式Customer:

@Entity
@Table
public class Customer { 
    @Id
    @GeneratedValue
    @Column(columnDefinition="serial")
    private int id;
}
Run Code Online (Sandbox Code Playgroud)

看来,使用@Column(columnDefinition="serial")主键会自动将引用它的外键设置到NOT NULL数据库中.将列类型指定为时,这确实是预期的行为serial吗?在这种情况下,是否有解决方案来启用可为空的外键?

先感谢您.

vca*_*tin 11

我找到了解决问题的方法.在实体中定义主键的方式Customer很好,问题在于外键声明.它应该像这样声明:

@ManyToOne
@JoinColumn(columnDefinition="integer", name="customer_id")
private Customer customer;
Run Code Online (Sandbox Code Playgroud)

实际上,如果columnDefinition="integer"省略该属性,则默认情况下将外键设置为源列:具有自己序列的非空序列.这当然不是我们想要的,因为我们只想引用自动递增的ID,而不是创建一个新ID.

此外,name=customer_id正如我在执行某些测试时所观察到的那样,似乎也需要该属性.否则,外键列仍将设置为源列.在我看来,这是一种奇怪的行为.欢迎提供评论或其他信息以澄清这一点!

最后,此解决方案的优点是ID由数据库(而不是JPA)生成,因此在手动插入数据或通过数据迁移或维护中经常发生的脚本时,我们不必担心它.


osc*_*ter 7

我遇到了这个问题,但我能够这样解决:

@ManyToOne
@JoinColumn(nullable = true)
private Customer customer;
Run Code Online (Sandbox Code Playgroud)

也许这个问题来自宣告 @ManyToOne(optional = true)

  • `nullable = false` ?? `FALSE`?为什么'假',而不是'真'? (6认同)