JPA多对多坚持加入表 [英] JPA many-to-many persist to join table

查看:97
本文介绍了JPA多对多坚持加入表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个表具有多对多关系.当我坚持用户不插入任何东西来联接表时,我映射了这两个实体.我一直在调试,直到坚持,我看到组列表不为空.

I have two table with many-to-many relations. I mapped this two entities when I am persisting users doesn't insert anything to join table. I am debugging till the persist, I see groups list is not null.

没有错误消息,只是坚持用户.

Ther is no error message just persist user.

用户<->用户组<->组

users <--> user-group <--> groups

我正在使用netbeans 7.3,Glassfish 3.1.2.2,postgresql 9.1和eclipselink 2

I am using netbeans 7.3, Glassfish 3.1.2.2, postgresql 9.1 and eclipselink 2

此外,我试图显示下面的属性对我不起作用的sql脚本.

Also, I tried to show sql scripts that properties below doesn't work for me.

        <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"/>

摘要AAO:

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进行的所有操作.

You need to enable cascade for merge (using PERSIST) or all operations with ALL.

@ManyToMany(mappedBy = "usersList", cascade = CascadeType.PERSIST)
private List<Groups> groupsList;


如果我设置CascadeType.PERSIST,它也会将数据插入到groups表中.我想添加日期用户表和用户组表(pk_user,pk_group)

If I set CascadeType.PERSIST, it insert data to groups table too. I want to add date users table and user_group table (pk_user, pk_group)

映射/联接表的工作方式是user_groupusergroup表上具有外键约束.这就是为什么必须在group中插入新行作为其主键的原因,以便将新行添加到user_group.

The way a mapping/join table works is that user_group would have a foreign key constraint on user and group table. That's why a new row in group has to be inserted for its primary key to be used to add a new row to user_group.

这与JPA无关,即使您使用的是普通JDBC,这也同样适用于您.这是实体关系在数据库中的工作方式.

This has nothing to do with JPA and the same would apply to you even if you were using plain JDBC instead. This is how Entity-Relationships work in database.

我也删除了所有表,它们是由eclipse链接自动生成的.它们是相同的,但不要在"user_group"中插入任何行.

Also I dropped all tables and they were generated by eclipse link automatically. They are same but don't insert any row to 'user_group'.

此行为由为您的persistence-unit指定的eclipselink.ddl-generation属性控制.当指定为drop-and-create-tables时,EclipseLink将重新创建整个数据库模式(删除进程中的任何现有数据).

This behaviour is controlled by the eclipselink.ddl-generation property specified for your persistence-unit. When specified as drop-and-create-tables, EclipseLink recreates the whole database schema (deleting any existing data in the process).

<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>

但是,启用此功能只是为了简化您的开发.不应在通过指定此属性或将其值设置为none禁用该功能的生产环境中使用此功能.

This, however, is enabled just to ease your development. This isn't supposed to be used in production environments where its disabled by not specifying this property or by setting its value as none.

<property name="eclipselink.ddl-generation" value="none"/>

这篇关于JPA多对多坚持加入表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆