2013-10-19 45 views
4

我有兩個表與多對多的關係。當我堅持用戶不插入任何東西來連接表時,我映射了這兩個實體。我正在調試,直到堅持,我看到組列表不爲空。JPA多對多持續加入表

Ther沒有錯誤信息只是堅持用戶。

用戶< - >用戶組< - >基團

我使用的netbeans 7.3,Glassfish的3.1.2.2,PostgreSQL的9.1和2的EclipseLink

另外,我試圖表明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; 
    } 
} 

回答

7

您需要啓用cascade進行合併(使用PERSIST)或者所有操作使用ALL

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

如果我設置CascadeType.PERSIST,將其插入到數據表組過。我要添加日期用戶表和USER_GROUP表(pk_user,pk_group)

的方式映射/連接表的工作原理是,user_group會對usergroup外鍵約束。這就是爲什麼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"/> 
+0

如果我設置了CascadeType.PERSIST,它也會將數據插入到組表中。我想添加日期用戶表和user_group表(pk_user,pk_group) – erdoganonur

+0

這非常不尋常。 'user_group'會有一個依賴於'group'表的外鍵約束。這就是爲什麼'group'被插入,然後它的主鍵用於向'user_group'添加一個新行。否則這是不可能的。 –

+0

'user_group'與'group'和'user'表具有fk。我也刪除了所有的表格,並且它們是由eclipse鏈接自動生成的。他們是相同的,但不插入任何行'user_group' – erdoganonur

1

爲了您要告訴SQL腳本的第一個問題,我已經在persistence.xml添加該代碼

<properties> 
    <property name="eclipselink.logging.level.sql" value="FINE"/> 
    <property name="eclipselink.logging.parameters" value="true"/> 
</properties> 

之後,清理並生成,然後部署。 JPA執行的SQL將顯示在netbeans的glassfish域日誌中。

關於多對多關係的第二個問題。

我在同一場景中遇到了同樣的問題,因爲我必須實現Web安全性,而且我需要與您使用的關係相同。無論如何,我發現問題不在實體中。

你必須檢查(在我的情況下)在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腳本。

希望它有幫助!

Mike