我正在尝试保存具有所选公司和地区的用户类别。用户与公司有多对多关系,而区域则有多对多关系。 这给了我错误:分离实体传递为持久化:
我不确定是什么问题
USER:
@Entity
@Table(name = "NPRO_USUARIOS")
public class User implements Serializable {
private static final long serialVersionUID = -1330075515340995797L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="user_seq_gen")
@SequenceGenerator(name="user_seq_gen", sequenceName="TELCO_NPRO_USER_SEQ")
@NotNull
private int id_usuario;
@NotNull
private String nombre_usuario;
@ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.REMOVE, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
@JoinTable(name = "NPRO_USUARIOS_SOCIEDADES_AREAS", joinColumns = @JoinColumn(name = "id_usuario"), inverseJoinColumns = @JoinColumn(name = "id_sociedad"))
private Set<Sociedad> listaSociedad;
@Transient
private String sociedades;
// Si el area es nula, el usuario estara asignado a todas las areas
@ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.REMOVE, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
@JoinTable(name = "NPRO_USUARIOS_SOCIEDADES_AREAS", joinColumns = @JoinColumn(name = "id_usuario"), inverseJoinColumns = @JoinColumn(name = "id_area"))
private Set<Area> listAreas;
@Transient
private String areas;
@NotNull
private String matricula_usuario;
@NotNull
private String email_usuario;
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
@JoinTable(name = "NPRO_PERFILES_USUARIOS", joinColumns = @JoinColumn(name = "id_usuario"), inverseJoinColumns = @JoinColumn(name = "id_rol"))
private Set<Role> listaRoles;
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
@JoinTable(name = "NPRO_PERFILES_USUARIOS", joinColumns = @JoinColumn(name = "id_usuario"), inverseJoinColumns = @JoinColumn(name = "id_pantalla"))
private Set<Pantalla> listaPantallas;
private LocalDateTime fecha_ultimo_acceso;
private String observaciones;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "usuario_modif")
private User usuario_modif;
}
公司:
@Entity
@Table(name = "NPRO_MAESTRO_SOCIEDADES")
public class Sociedad implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull
private int id_sociedad;
@NotNull
private String cod_sociedad;
@NotNull
private String cod_sociedad_gl;
@NotNull
private String nombre_sociedad;
@NotNull
private String cif_sociedad;
private String observaciones;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "usuario_modif")
private User usuario_modif;
private String activo;
@JsonIgnore
@ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.REMOVE, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
@JoinTable(name = "NPRO_USUARIOS_SOCIEDADES_AREAS", joinColumns = @JoinColumn(name = "id_sociedad"), inverseJoinColumns = @JoinColumn(name = "id_usuario"))
private Set<User> listaUsuarios;
}
区域:
@Entity
@Table(name = "NPRO_MAESTRO_AREAS")
public class Area implements Serializable {
private static final long serialVersionUID = -1330075515340995797L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="area_seq_gen")
@SequenceGenerator(name="area_seq_gen", sequenceName="TELCO_NPRO_AREAS_SEQ")
@NotNull
private int id_area;
@NotNull
private String nombre_area;
private LocalDateTime fecha_modif;
private String observaciones;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "usuario_modif")
private User usuario_modif;
@NotNull
private String activo;
@ManyToOne
@JoinColumn(name="id_sociedad")
private Sociedad sociedad;
@JsonIgnore
@ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.REMOVE, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
@JoinTable(name = "NPRO_USUARIOS_SOCIEDADES_AREAS", joinColumns = @JoinColumn(name = "id_area"), inverseJoinColumns = @JoinColumn(name = "id_usuario"))
private Set<User> listaUsuarios;
}
我正在使用springboot jpa存储库保存方法
@Override
public User save(User user) {
return userRepository.save(user);
}
这是完整的错误: 2020-06-09 15:49:02.371 [nio-8080-exec-4] .mmaExceptionHandlerExceptionResolver:由处理程序执行引起的已解决异常:org.springframework.dao.InvalidDataAccessApiUsageException:传递给持久对象的分离实体:com.telefonica.npro。模型。区域;嵌套异常是org.hibernate.PersistentObjectException:传递给持久对象的分离实体:com.telefonica.npro.model.Area
预先感谢
编辑:
我正在此页面中阅读有关错误的信息 http://knowledgespleasure.blogspot.com/2015/06/understand-detached-entity-passed-to.html
我想我的问题是最后一个问题:
另一方面,如果要求从不添加新的子对象(如果它在数据库中不是必需的),则应删除CascadeType.PERSIST并应使用cascade = {CascadeType.MERGE,CascadeType.REFRESH}
用户始终与公司和地区相关,并且它们已经存在,不会成为新用户。 但是,如果我删除了PERSIST,那么在公共表中插入一个id为null的尝试 NPRO_USUARIOS_SOCIEDADES_AREAS
有帮助吗?
答案 0 :(得分:0)
我将解释您对@ManyToMany
和User
实体之间的Area
双向关系的问题。
一个bidirectional @ManyToMany关联应该拥有一个所有权和一个mappedBy
一方。 CascadeType
应该仅出现在此关联的一侧。
如this文章中所述,否则需要使双方同步,否则将破坏域模型关系的一致性,除非双方都正确,否则不能保证实体状态转换有效已同步。
因此,User
实体定义了addArea
和removeArea
实体状态同步方法。
因此,您应该通过以下方式更正 User-Area @ManyToMany
映射:
@Entity
@Table(name = "NPRO_USUARIOS")
public class User implements Serializable {
// ...
@ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.REMOVE, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
@JoinTable(name = "NPRO_USUARIOS_SOCIEDADES_AREAS", joinColumns = @JoinColumn(name = "id_usuario"), inverseJoinColumns = @JoinColumn(name = "id_area"))
private Set<Area> listAreas;
public User()
{
listAreas = new HashSet<>();
}
public void addArea(Area area) {
listAreas.add(area);
area.getUsers().add(this);
}
public void removeArea(Area area) {
listAreas.remove(area);
area.getUsers().remove(this);
}
}
@Entity
@Table(name = "NPRO_MAESTRO_AREAS")
public class Area implements Serializable {
// ...
@JsonIgnore
@ManyToMany(mappedBy = "listAreas")
private Set<User> listaUsuarios;
}
然后您可以通过以下方式保存新用户:
User user = new User();
// ...
Area area1 = new Area();
// ...
user.addArea(area1);
Area area2 = new Area();
// ...
user.addArea(area2);
userRepository.save(user);
应该对 User-Sociedad 关系进行类似的修正。