我有,我想成为一个可空多到一的关系:
@ManyToOne(optional = true)
@JoinColumn(name = "customer_id", nullable = true)
private Customer customer;
不幸的是,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;
}
看来,使用@Column(columnDefinition="serial")
作为主键自动设置外键引用它来NOT NULL
在数据库中。 那真的是指定列类型时预期的行为serial
? 有没有在这种情况下能够为空的外键一个解决方法吗?
先感谢您。
我找到了解决我的问题。 主键是实体定义方式Customer
是好的,问题存在于外键声明。 应该声明如下:
@ManyToOne
@JoinColumn(columnDefinition="integer", name="customer_id")
private Customer customer;
事实上,如果属性columnDefinition="integer"
省略默认情况下,外键将被设置为源列:非空系列都有自己的序列。 这当然是我们希望不是,因为我们只是希望引用自动递增的ID,而不是创建一个新的。
此外,它似乎属性name=customer_id
为我进行了一些测试时所观察到的也是必需的。 否则,外键列将仍然被设置为源列。 这在我看来是一个奇怪的行为。 评论或其他信息,以澄清这是欢迎!
最后,这种解决方案的优点是,由所述数据库(未由JPA)产生的ID,因此我们没有手动或通过其通常发生在数据迁移或维护脚本插入数据时,担心。
我遇到了这个问题,但我还是能够解决这样说:
@ManyToOne
@JoinColumn(nullable = true)
private Customer customer;
也许问题的声明出现@ManyToOne(optional = true)
这是非常奇怪的。
在JPA可为空参数默认为true。 我使用这种配置的所有的时间和它工作正常。 如果你试图挽救实体应该是成功的。
你尝试删除为该关系创建的表? 也许你有旧的表,该列?
或者,也许你应该试着去发现的代码其他块的解决方案,因为这是正确的配置。
注:我试图在PostgreSQL上这个配置与JPA2和Hibernate。
编辑
在这种情况下,也许你可以尝试主键的一点点不同的定义。
例如,你可以使用定义是这样的:
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column()
private Long id;
和PostgreSQL将产生
id bigint NOT NULL
-- with constraint
CONSTRAINT some_table_pkey PRIMARY KEY (id)
如果这是不够好,你可以尝试此解决方案。
内交易,但之前的保存操作,明确设置外键的列值作为空。 通过这种休眠,从来都不是外键关联的表执行SELECT查询,不抛出异常“冲洗之前保存的瞬态的实例”。 如果要设置“空值”有条件,然后执行1.获取和使用回购调用get /找到2.然后检查的条件获取的值,并将其设置相应空设定值.pasted低于该测试代码发现工作
// Transaction Start
Optional<Customer> customerObject = customerRepository.findByCustomerId(customer.getCustomerId())
if(customerObject.isPresent())yourEnclosingEntityObject.setCustomer(customerObject)}
else {yourEnclosingEntityObject.setCustomer(null)}
yourEnclosingEntityObjectRepository.save(yourEnclosingEntityObject)
// Transaction End