JPA,已经持久化的对象给出 "a new object was found through a relationship that was not marked cascade PERSIST"
JPA, already persisted object gives "a new object was found through a relationship that was not marked cascade PERSIST"
我想了解为什么在坚持 Tournament
时出现错误,但在坚持 Match
.
时却没有
错误:
Caused by: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: main.java.entities.Team@3eff51aa.
Match
和 Tournament
都没有用 cascade persist
注释的 team
实体。然而匹配仍然没有错误地持续存在。
所以它是这样工作的:我可以创建 Thethread
实体,它可以是 Tournament
或 Match
(不是两者)。创建 Match
或 Thethread
时,我从数据库加载不同的 Teams
,我可以 select 哪个团队参与什么。例如一场比赛将有 2 支球队参加,而一场锦标赛将有球队分组(a、b、c 组等)。我看到这两者之间的唯一区别是一个关系是 @ManyToMany
,另一个是 @ManyToOne
。一支球队有很多场比赛,但一场比赛只有一场 teamA(和一场 teamB)。一个tournament
有很多Groups
,一个group
有很多teams
,一个team
有很多groups
。
请注意,在这两种情况下,团队都没有 CascadeType.Persist(这是我不想要的,因为我是从数据库中获取它们的,坚持这些会造成重复)。
线程
public class Thethread implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="idthread")
private long idthread;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "categories_idcategory")
private Category category;
@OneToOne(mappedBy = "thread", cascade = CascadeType.PERSIST)
private Match match;
@OneToOne(mappedBy="thread", cascade = CascadeType.PERSIST)
private Tournament tournie;
匹配
public class Match implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_match")
private long idmatch;
@OneToOne
@JoinColumn(name = "idthread")
private Thethread thread;
@NotNull
@ManyToOne
@JoinColumn(name = "team_a")
private Team teamA;
@NotNull
@ManyToOne
@JoinColumn(name = "team_b")
private Team teamB;
锦标赛
@Entity
@Table(name="layout_tournament")
public class Tournament implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="idlayout_tournament")
private int idtournie;
@OneToMany(mappedBy="tournie", cascade = CascadeType.PERSIST)
private List<TournamentGroup> groups;
@OneToOne
@JoinColumn(name="thread")
private Thethread thread;
}
锦标赛组:
public class TournamentGroup implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="idtournie_group")
private int idgroup;
@ManyToOne
@JoinColumn(name="tournie")
private Tournament tournie;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="team_has_tournie_group",
joinColumns=
@JoinColumn(name="tournie_group"),
inverseJoinColumns=
@JoinColumn(name="team"))
private List<Team> teams;
}
当持久化到数据库中时,我是这样做的:
@Override
public void updateLatestThreadCategory(long id, Thethread latestThread) {
// Query query = em.createQuery(JPQL_FIND_BY_ID, Category.class);
// query.setParameter("id", id);
// if(null != latestThread.getTournie()){
// if(null != latestThread.getTournie().getGroups()){
// for (TournamentGroup g : latestThread.getTournie().getGroups()){
// for(Team t : g.getTeams()){
// t = em.getReference(Team.class, t.getIdteams());
// }
// }
// }
// }
em.persist(latestThread);
Category cat = em.getReference(Category.class, id);
cat.setlastThread(latestThread);
评论部分是我试图让团队被管理但是没有用。
如果有人读到这里,我有两个问题:
- 为什么我可以坚持一个包含比赛的线程而没有问题,但我在一个包含锦标赛的线程中遇到错误。(请注意,球队是从数据库中提取的,但我想在这两种情况下都不是'管理 )?
- 当我保留包含 teamA 和 teamB 的比赛时:JPA 是简单地在比赛中写入球队的 ID table 还是它也更新球队?因此,如果有人决定创建一场比赛,他首先会请求出现在下拉列表中的球队。同时,如果团队所有者决定编辑他的团队并在数据库中更新它。然后创建一场比赛,与未编辑的球队一起,编辑将被覆盖,对吗?
我正在使用 EclipseLink 2.6
我创建了另一个实体来表示多对多关联之间的 table。错误消失了,但我改变了很多东西,所以我不能保证它是解决问题的原因。至于为什么会出现这种情况,我认为是因为该团队存在于团队 table 中,但尚未在 table 中进行 manytomany 关联。
我想了解为什么在坚持 Tournament
时出现错误,但在坚持 Match
.
错误:
Caused by: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: main.java.entities.Team@3eff51aa.
Match
和 Tournament
都没有用 cascade persist
注释的 team
实体。然而匹配仍然没有错误地持续存在。
所以它是这样工作的:我可以创建 Thethread
实体,它可以是 Tournament
或 Match
(不是两者)。创建 Match
或 Thethread
时,我从数据库加载不同的 Teams
,我可以 select 哪个团队参与什么。例如一场比赛将有 2 支球队参加,而一场锦标赛将有球队分组(a、b、c 组等)。我看到这两者之间的唯一区别是一个关系是 @ManyToMany
,另一个是 @ManyToOne
。一支球队有很多场比赛,但一场比赛只有一场 teamA(和一场 teamB)。一个tournament
有很多Groups
,一个group
有很多teams
,一个team
有很多groups
。
请注意,在这两种情况下,团队都没有 CascadeType.Persist(这是我不想要的,因为我是从数据库中获取它们的,坚持这些会造成重复)。
线程
public class Thethread implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="idthread")
private long idthread;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "categories_idcategory")
private Category category;
@OneToOne(mappedBy = "thread", cascade = CascadeType.PERSIST)
private Match match;
@OneToOne(mappedBy="thread", cascade = CascadeType.PERSIST)
private Tournament tournie;
匹配
public class Match implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_match")
private long idmatch;
@OneToOne
@JoinColumn(name = "idthread")
private Thethread thread;
@NotNull
@ManyToOne
@JoinColumn(name = "team_a")
private Team teamA;
@NotNull
@ManyToOne
@JoinColumn(name = "team_b")
private Team teamB;
锦标赛
@Entity
@Table(name="layout_tournament")
public class Tournament implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="idlayout_tournament")
private int idtournie;
@OneToMany(mappedBy="tournie", cascade = CascadeType.PERSIST)
private List<TournamentGroup> groups;
@OneToOne
@JoinColumn(name="thread")
private Thethread thread;
}
锦标赛组:
public class TournamentGroup implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="idtournie_group")
private int idgroup;
@ManyToOne
@JoinColumn(name="tournie")
private Tournament tournie;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="team_has_tournie_group",
joinColumns=
@JoinColumn(name="tournie_group"),
inverseJoinColumns=
@JoinColumn(name="team"))
private List<Team> teams;
}
当持久化到数据库中时,我是这样做的:
@Override
public void updateLatestThreadCategory(long id, Thethread latestThread) {
// Query query = em.createQuery(JPQL_FIND_BY_ID, Category.class);
// query.setParameter("id", id);
// if(null != latestThread.getTournie()){
// if(null != latestThread.getTournie().getGroups()){
// for (TournamentGroup g : latestThread.getTournie().getGroups()){
// for(Team t : g.getTeams()){
// t = em.getReference(Team.class, t.getIdteams());
// }
// }
// }
// }
em.persist(latestThread);
Category cat = em.getReference(Category.class, id);
cat.setlastThread(latestThread);
评论部分是我试图让团队被管理但是没有用。
如果有人读到这里,我有两个问题:
- 为什么我可以坚持一个包含比赛的线程而没有问题,但我在一个包含锦标赛的线程中遇到错误。(请注意,球队是从数据库中提取的,但我想在这两种情况下都不是'管理 )?
- 当我保留包含 teamA 和 teamB 的比赛时:JPA 是简单地在比赛中写入球队的 ID table 还是它也更新球队?因此,如果有人决定创建一场比赛,他首先会请求出现在下拉列表中的球队。同时,如果团队所有者决定编辑他的团队并在数据库中更新它。然后创建一场比赛,与未编辑的球队一起,编辑将被覆盖,对吗?
我正在使用 EclipseLink 2.6
我创建了另一个实体来表示多对多关联之间的 table。错误消失了,但我改变了很多东西,所以我不能保证它是解决问题的原因。至于为什么会出现这种情况,我认为是因为该团队存在于团队 table 中,但尚未在 table 中进行 manytomany 关联。