【发布时间】:2014-05-01 16:52:45
【问题描述】:
我有一个包含子实体的聚合。当我保存聚合时,聚合和子实体的 ID 不会更新。有没有办法让 JPA 实体管理器自动更新 ID,或者是唯一的解决方案来保存并获取返回聚合然后找到您刚刚添加的子实体?我正在使用 Spring CrudRepositories 来保存我的所有聚合。
我正在使用:
春季 4.0.3
休眠 4.3.5
JPA 2.1
这是我拥有的基本代码。
@MappedSuperclass
public class AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
protected Long id;
}
@Entity
@Table(name = "foo")
public class Foo extends AbstractEntity{
@OneToMany(cascade=CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "foo")
private List<Bar> bars;
public void addBar(Bar bar)
{
bar.setBar
bars.add(bar);
}
}
@Entity
@Table(name = "bar")
public class Bar extends AbstractEntity{
@ManyToOne
@JoinColumn(name = "foo_id", nullable = false)
private Foo foo;
protected setFoo(Foo foo){
this.foo = foo;
}
}
@Repository
@Transactional(propagation = Propagation.MANDATORY)
interface FooRepository extends CrudRepository<Foo, Long> {
}
@Service
public class DoStuffService()
{
@AutoInject
private FooRepository fooRepository;
public Bar doStuff(long id)
{
Foo foo = fooRepository.findOne(id);
Bar bar = createSomeBar();
foo.addBar(bar);
fooRepository.save(foo);
return bar; // I would like this to have the id filled out from the save of the aggregate rather than having to go to the get the Foo again and go through the collection to find the right bar so I can return it with an ID.
}
}
@Service
@Transactional
public class SomeRootServiceService()
{
@AutoInject
private DoStuffService doStuffService;
public Bar doRootStuff()
{
Bar bar = doStuffService.doStuff(someId);
if (bar.getId() == null){
//Should never get here but I do.
}
}
}
编辑:添加一些信息来阐明我们的最终目标是什么,id 问题只是其中的一个症状。
我们真正想做的是获取一个从聚合中创建的实体,并将其传递给在同一个数据库事务中链接到新创建的实体的其他东西,因为该实体不是然而“已保存”的休眠会引发瞬态实体错误。
【问题讨论】:
-
你在你的 id 字段上使用@GeneratedValue 吗?
-
是的,很抱歉忘记将其包含在原始问题中。更新了描述以显示我的 id 是如何注释的。
-
我不明白为什么你的问题被否决了。我相信这是一个合理的问题。无论如何,请包括您的实体的代码,实际保存的代码和您得到的错误/不需要的结果
-
添加了正在发生的事情的代码。
-
如何测试没有生成 ID?您在哪里访问 ID?你为什么要调用 fooRepository.save(foo)? foo 是一个托管实体。它将自动、透明地保存。你为什么不设置酒吧的 foo。这是必要的。