如果我不分两步执行实体角色设置(两个持续存在),为什么此单元测试失败。 错误是:
java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: io.osram.olt.extension.jpa.Role@16daa399.
private Role addRoleWithId(String roleId){
Role myRole = new Role();
myRole.setRoleId(roleId);
myRole.setRealmId("my");
myRole.setDescription("role-description-0");
myRole.setExternalCreator(true);
myRole.setName("role-name-0");
em.persist(myRole); //<--- Without this persisting the role fails with the error above.
//Setup joins:
myRole.setAContext(getApplications().get(0));
myRole.setAnotherContext(getTenants().get(0));
em.persist(myRole);
return myRole;
}
...
角色实体:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ANOTHER_CONTEXT_ID")
private AnotherContext anotherContext;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ACONTEXT_ID")
private AContext aContext;
...
public Role setAContext(AContext aContext) {
this.aContext = aContext;
if(aContext != null) {
aContext.addRole(this);
}
return this;
}
public Role setAnotherContext(AnotherContext anotherContext) {
this.anotherContext = anotherContext;
if(anotherContext != null){
anotherContext.addRole(this);
}
return this;
}
...
AContext和AnotherContext都包含与角色类似的关系:
@OneToMany
@JoinTable(
name="OLT_ROLES_ACONTEXT",
joinColumns = @JoinColumn( name="ACONTEXT_ID"),
inverseJoinColumns = @JoinColumn( name="ROLE_ID")
)
private Set<Role> roles = new HashSet<Role>();
似乎通过两步创建对象,我可以避免使用级联。
答案 0 :(得分:0)
在setAContext
和setAnotherContext
方法中,您正在尝试设置尚未保留的Role
对象。
很明显,在设置上下文之前,如果没有指定em.persist(myRole);
,它将无法使用CaseCadeType.PERSIST
。
答案 1 :(得分:0)
级联的默认设置是级联NONE,这会导致默认情况下持久化实体中的关系不会保留。
必然结果是,如果在没有管理关系的情况下尝试将没有cascade.PERSIST的实体持久化到它的关系,则会得到上述异常。
推论的一个例外是,如果您持久存在的实体是关系的所有者,并且关系中的属性已经存在于数据库中,则yo将能够保留它。
我在映射中注意到的一件小事:它是一个双向单向,一个带有连接列,另一个带有连接表,所以这是有意的吗?