Hibernate中的OneToMany单向映射。在引用实体中设置外键设置

时间:2015-01-11 08:32:46

标签: java mysql spring hibernate

假设有两个实体: Child ,{em}从 Parent Child

@OneToMany

正如您所看到的,在我的例子中, Child 表将一个外键存储到 Parent 的主键中。但我不希望在我的Child实体中将其作为双向映射。

现在出现的问题是,我无法在class Parent { @Column(name="id") private Long id; @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "parent_id", referencedColumnName = "id") private List<Child> children; } class Child { @Column(name="id") private Long id; @Column(name="parent_id") private Long parentId; } 个实例中设置parent_id

我创建了这样的实例:

Child

假设父端有级联。此方法首先保存Parent,然后保存Child实例。然后它在子实例上运行更新查询以更新Parent parent = new Parent(); parent.setChildren(Lists.newArrayList(new Child(), new Child())); parentDomainService.save(parent); ,正如我从Hibernate show_sql日志中看到的那样。但令人惊讶的是,在更新查询后,我看到一些parent_idchildparent_id。这让我很惊讶。

所以,我去手动处理那件事,并删除了级联。然后我保存了这样的实体:

null

这一个反弹在我身上,但有以下例外:

Parent parent = new Parent();
parent.setChildren(Lists.newArrayList(new Child(), new Child()));
parent = parentDomainService.save(parent);

for (Child child: parent.getChildren()) {
    child.setParentId(parent.getId());
} 

childDomainService.save(parent.getChildren());

我在SO上看到了很多关于异常的问题,而且我知道有很多问题,但是几乎所有问题都在处理双向映射,或者使用JoinTable进行单向映射。它们都不适合我的情况。

这有什么灯吗?我没有选择。

P.S。:我正在处理的实际场景需要节省大量数据。例如:50000个父记录和250000个子记录。这就是为什么我不想要双向映射。因为保存Child会在后端创建一个带有连接表的查询。

我最感兴趣的是解决方案,其中我不必在org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.somepkg.Child 表上触发两次查询。正如我当前的应用程序中发生的那样,这妨碍了性能。

1 个答案:

答案 0 :(得分:4)

删除级联时,父级不会保留引用的子元素,而是

parent = parentDomainService.save(parent);

父引用“未保存的瞬态”子实例,因此抛出异常。如果您先保存父项,然后添加子项:

Parent parent = new Parent();
parent = parentDomainService.save(parent);
parent.setChildren(Lists.newArrayList(new Child(), new Child()));

for (Child child: parent.getChildren()) {
    child.setParentId(parent.getId());
} 

childDomainService.save(parent.getChildren());

然后不会抛出异常。