[英]Spring Boot JPA, data do not persist in join table of many-to-many relationship
[英]JPA many-to-many persist to join table
我有两张表与多对多的关系。 当我持久化用户没有插入任何东西来连接表时,我映射了这两个实体。 我正在调试直到持久化,我看到组列表不为空。
Ther是没有错误消息只是坚持用户。
用户< - >用户组< - >组
我使用的是netbeans 7.3,Glassfish 3.1.2.2,postgresql 9.1和eclipselink 2
此外,我试图显示sql脚本,下面的属性不适合我。
<property name="eclipselink.logging.logger" value="ServerLogger"/>
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
Abstact DAO:
public abstract class GenericDAO<E> implements Serializable{
@PersistenceContext
EntityManager entityManager;
public void persist(E object){
entityManager.persist(object);
}
public void merge(E object){
entityManager.merge(object);
}
public void delete(E object){
object = entityManager.merge(object);
entityManager.remove(object);
}
}
用户实体:
@Entity
@Table(name = "users")
@XmlRootElement
@NamedQueries(
{
@NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
@NamedQuery(name = "Users.findByUserId", query = "SELECT u FROM Users u WHERE u.userId = :userId"),
@NamedQuery(name = "Users.findByName", query = "SELECT u FROM Users u WHERE u.name = :name"),
@NamedQuery(name = "Users.findBySurname", query = "SELECT u FROM Users u WHERE u.surname = :surname"),
@NamedQuery(name = "Users.findByEmail", query = "SELECT u FROM Users u WHERE u.email = :email"),
@NamedQuery(name = "Users.findByUsername", query = "SELECT u FROM Users u WHERE u.username = :username"),
@NamedQuery(name = "Users.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password")
})
public class Users implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "user_id")
private Integer userId;
@Size(max = 2147483647)
@Column(name = "name")
private String name;
@Size(max = 2147483647)
@Column(name = "surname")
private String surname;
// @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
@Size(max = 2147483647)
@Column(name = "email")
private String email;
@Size(max = 2147483647)
@Column(name = "username")
private String username;
@Size(max = 2147483647)
@Column(name = "password")
private String password;
@ManyToMany(mappedBy = "usersList")
private List<Groups> groupsList;
@OneToMany(mappedBy = "userId")
private List<Person> personList;
//Getters Setters
团体实体:
@Entity
@Table(name = "groups")
@XmlRootElement
@NamedQueries(
{
@NamedQuery(name = "Groups.findAll", query = "SELECT g FROM Groups g"),
@NamedQuery(name = "Groups.findByGroupId", query = "SELECT g FROM Groups g WHERE g.groupId = :groupId"),
@NamedQuery(name = "Groups.findByGroupName", query = "SELECT g FROM Groups g WHERE g.groupName = :groupName"),
@NamedQuery(name = "Groups.findByGroupDescription", query = "SELECT g FROM Groups g WHERE g.groupDescription = :groupDescription")
})
public class Groups implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "group_id")
private Integer groupId;
@Size(max = 2147483647)
@Column(name = "group_name")
private String groupName;
@Size(max = 2147483647)
@Column(name = "group_description")
private String groupDescription;
@JoinTable(name = "user_group", joinColumns =
{
@JoinColumn(name = "group_id", referencedColumnName = "group_id")
}, inverseJoinColumns =
{
@JoinColumn(name = "user_id", referencedColumnName = "user_id")
})
@ManyToMany(fetch = FetchType.EAGER)
private List<Users> usersList;
//Getters Setters
用户DAO:
public class UserDAO extends GenericDAO<Users> implements Serializable {
public List<Users> getAllUsers()
{
Query query = entityManager.createNamedQuery("Users.findAll");
List<Users> users = query.getResultList();
return users;
}
}
您需要启用cascade
以进行合并(使用PERSIST
)或所有操作使用ALL
。
@ManyToMany(mappedBy = "usersList", cascade = CascadeType.PERSIST)
private List<Groups> groupsList;
如果我设置CascadeType.PERSIST,它也会将数据插入到组表中。 我想添加日期用户表和user_group表(pk_user,pk_group)
映射/连接表的工作方式是user_group
在user
和group
表上具有外键约束。 这就是为什么必须插入group
的新行以使其主键用于向user_group
添加新行。
这与JPA无关,即使您使用的是普通的JDBC,它也适用于您。 这就是实体关系在数据库中的工作方式。
我也删除了所有表,它们是由eclipse链接自动生成的。 它们相同但不向'user_group'插入任何行。
此行为由为persistence-unit
指定的eclipselink.ddl-generation
属性控制。 当指定为drop-and-create-tables
,EclipseLink将重新创建整个数据库模式(删除进程中的所有现有数据)。
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
但是,这只是为了简化您的开发。 通过不指定此属性或将其值设置为none
,禁止在禁用它的生产环境中使用它。
<property name="eclipselink.ddl-generation" value="none"/>
关于你要显示sql脚本的第一个问题,我在persistence.xml中添加了这段代码
<properties>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
</properties>
之后,清理并构建然后部署。 JPA执行的sql将显示在netbeans的glassfish域日志中。
关于多对多关系的第二个问题。
我在同一场景中遇到了同样的问题,因为我要实现网络安全,我需要你正在使用的相同关系。 无论如何,我发现问题不在实体中。
您必须检查(对于我的情况)UserJPAController.java上的插入和编辑方法,这些方法有些如何知道实体如何相互引用,所以我实现了这个代码,它工作正常。
List<Grupo> attachedGrupoList = new ArrayList<Grupo>();
for (Grupo grupoListGrupoToAttach : usuario.getGrupoList()) {
grupoListGrupoToAttach = em.getReference(grupoListGrupoToAttach.getClass(), grupoListGrupoToAttach.getIdGrupo());
attachedGrupoList.add(grupoListGrupoToAttach);
}
usuario.setGrupoList(attachedGrupoList);
em.persist(usuario);
for (Grupo grupoListGrupo : usuario.getGrupoList()) {
grupoListGrupo.getUsuarioList().add(usuario);
grupoListGrupo = em.merge(grupoListGrupo);
}
执行该代码并且事务结束后,您将在数据库中看到JPA执行的sql脚本。
希望能帮助到你!
麦克风
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.