gpt4 book ai didi

java - 如何在 Hibernate 中的集合之间移动项目

转载 作者:搜寻专家 更新时间:2023-11-01 02:43:54 24 4
gpt4 key购买 nike

我在我的应用程序中映射了两个实体,以便为 Team 及其 Members 建模。一个 Team 可以有很多 Members 并且一个 Member 只能属于一个 Team。处理这个概念一切都很好。当我尝试将一个 Member 从一个现有的 Team 移动到另一个时,问题就来了。

实体在下面以简化形式呈现。最后一个方法,transfer(),应该从其 Team 中删除某个 Member 并将其发送给另一个一。

@Entity
public class Member extends Person {
@ManyToOne
private Team team;

protected Member() {
super();
}

public Member(Team team, String name) {
super(name);
this.team = team;
}

// Trivial getters and setters...

public Team getTeam() {
return team;
}

protected void setTeam(Team team) {
this.team = team;
}
}

@Entity
public class Team {
@Id
private long id;
private String name;
@OneToMany(mappedBy="team", cascade=CascadeType.ALL)
private List<Member> members = new ArrayList<Member>();

protected Team() {
}

public Team(String name) {
this.name = name;
}

// trivial getters and setters...

public Member addMember(String name) {
Member member = new Member(this, name);
members.add(member);
return member;
}

protected void addMember(Member member) {
members.add(member);
member.setTeam(this);
}

public void removeMember(Member member) {
members.remove(member);
}

public Member memberByName(String memberName) {
for(Member member : members)
if(member.getName().equals(memberName))
return member;
return null;
}

public Collection<Members> getMembers() {
return Collections.unmodifiableCollection(members);
}

public void transfer(Member member, Team destination) {
members.remove(member);
destination.addMember(member);
}
}

我有这个用于验证传输服务的单元测试代码

Team teamA = teamRepository.teamById(idTeamA);
Team teamB = teamRepository.teamById(idTeamB);
Team teamC = teamRepository.teamById(idTeamC);

Member zaki = teamA.memberByName("Zaki");
Member denise = teamA.memberByName("Denise");

EntityTransaction t = teamRepository.transactionBegin();
teamA.transfer(zaki, teamB);
teamA.transferir(denise, teamC);
t.commit();

我在 commit() 行中有以下异常

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: application.domain.Member

有什么想法吗?

更新 1:

我决定进行一些测试,并将 transfer() 方法的代码更改如下

public void transfer(Member member, Team destination) {
member.setTeam(this);
}

结果很奇怪:没有错误,但也没有对表进行更新。 Hibernate 无法跟踪更新,传输根本就没有发生。

更新 2:

我决定尝试一下来自 Steve K 的建议并将 transfer() 方法更改为以下内容:

    public void transfer(Member member, Team destination) {
destination.addMember(member);
members.remove(member);
}

查看 addMember()removeMember() 方法(如下),我们看到 Team 也开始更新。

    protected void addMember(Member member) {
members.add(member);
member.setTeam(this);
}

public void removeMember(Member member) {
members.remove(member);
}

因此,成员被添加到目标集合,其团队被设置为目标 Team,然后成员被从当前集合中删除(当前 Team).

测试用例改为

EntityTransaction t = teamRepository.transactionBegin();
teamA.transfer(zaki, teamB);
teamA.getEntityManager().refresh(teamA); // I get an exception here!!!
t.commit();

refresh() 行我有以下异常:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: domain.Member
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
// ... many calls
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: domain.Member
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
// ... many calls
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1335)
... 28 more

毕竟,Hibernate 不支持将实例从一个集合转移到另一个集合(实现简单聚合)!

最佳答案

您的映射和数据访问逻辑都很好。

需要在代码开头移动事务边界:

EntityTransaction t = teamRepository.transactionBegin();

Team teamA = teamRepository.teamById(idTeamA);
...
teamA.transferir(denise, teamC);
t.commit();

但是您得到的异常不是来自您向我们展示的代码:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: application.domain.Member

可能有一个挂起的持久操作正在排队并且只有 translated during flush时间(在你的情况下提交时间)。所以你需要 activate the SQL logs被执行并尝试找出分离的实体。

关于java - 如何在 Hibernate 中的集合之间移动项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27016778/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com