2014-04-27 119 views
0

我的工作網站,用戶可以訂閱組織 retrive行。 當我要實現訂閱功能,我面臨以下問題。HQL查詢從多對多連接表

在排序我想創建ManyToMany連接表的模型類從表中檢索行以檢查哪些組織由用戶訂閱。 而在休眠我不能創建表沒有主鍵。但在聯接表中,一個用戶可以訂閱許多組織,一個組織有很多訂戶,所以主鍵重複,我得到異常ERROR: Duplicate entry '1' for key 'PRIMARY'

的hibernate.cfg.xml包含

<mapping class="model.User"/> 
<mapping class="model.Post"/> 
<mapping class="model.UserSubscribes"/> 

User.java

package model; 

@Entity 
@Table(name="user", 
     uniqueConstraints = {@UniqueConstraint(columnNames={"email"})} 
     ) 
@org.hibernate.annotations.Entity(dynamicUpdate=true,selectBeforeUpdate=true) 

public class User implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private long userId;//1 
    private String email;//1 
    private String password;// 

    public User(long userId, String email, String password){ 
     this.userId = userId; 
     this.email = email; 
     this.password = password; 
    } 

    @ManyToMany(fetch = FetchType.LAZY) 
    @JoinTable(
      name="UserSubscribes", 
      joinColumns={ @JoinColumn(name="userId",referencedColumnName="userId") }, 
      inverseJoinColumns={ @JoinColumn(name="orgId", referencedColumnName="orgId") } 
    ) 
    private Collection<Organisation> orgSubscribes = new ArrayList<Organisation>(); 


    //Getter & Setter 

} 

Organisation.java

package model; 

@Entity 
@Table(name="org", 
     uniqueConstraints = {@UniqueConstraint(columnNames={"email"})} 
     ) 
@org.hibernate.annotations.Entity(dynamicUpdate=true,selectBeforeUpdate=true) 

public class Organisation implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private long orgId; 
    private String email; 
    private String password; 

    public Organisation(long orgId, String email, String password){ 
     this.orgId = orgId; 
     this.email = email; 
     this.password = password; 
    } 

    //Getter & Setter 
} 

UserSubscribes.java

package model; 

@Entity 
@Table(name="UserSubscribes") 
public class UserSubscribes implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private long userId; 
    private long orgId; 

    //Getter & Setter 
} 

Subscribe.java

package view.action; 

public class Subscribe extends ActionSupport { 

    public String execute(){ 

     Session session = HibernateUtill.getSessionFactory().getCurrentSession(); 
     session.beginTransaction(); 

     System.out.println("Subscribbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); 

     User u1 = new User(1, "ppp", "ppp"); 
     User u2 = new User(2, "qqq", "qqq"); 
     Organisation o1 = new Organisation(1, "ppp", "ppp"); 
     Organisation o2 = new Organisation(2, "qqq", "qqq"); 
     Organisation o3 = new Organisation(3, "www", "www"); 
     Organisation o4 = new Organisation(4, "eee", "eee"); 

     session.save(o1); 
     session.save(o2); 
     session.save(o3); 
     session.save(o4); 
     session.save(u1); 
     session.save(u2); 

     u1.getOrgSubscribes().add(o1); 
     u1.getOrgSubscribes().add(o2); 
     u1.getOrgSubscribes().add(o3); 

     session.saveOrUpdate(u1); 

     session.getTransaction().commit(); 

     return SUCCESS; 
    } 
} 

,我得到這個輸出和錯誤

Subscribbbbbbbbbbbbbbbbbbbbbbbbbbbbb 
Hibernate: insert into org (email, password) values (?, ?) 
Hibernate: insert into org (email, password) values (?, ?) 
Hibernate: insert into org (email, password) values (?, ?) 
Hibernate: insert into org (email, password) values (?, ?) 
Hibernate: insert into user (email, password) values (?, ?) 
Hibernate: insert into user (email, password) values (?, ?) 
Hibernate: insert into UserSubscribes (userId, orgId) values (?, ?) 
Hibernate: insert into UserSubscribes (userId, orgId) values (?, ?) 
Apr 27, 2014 4:43:52 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions 
WARN: SQL Error: 1062, SQLState: 23000 
Apr 27, 2014 4:43:52 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions 
ERROR: Duplicate entry '1' for key 'PRIMARY' 

如果我從hibernate.cfg.xml中映射刪除<mapping class="model.UserSubscribes"/>則完美如下輸出。

Subscribbbbbbbbbbbbbbbbbbbbbbbbbbbbb 
Hibernate: insert into org (email, password) values (?, ?) 
Hibernate: insert into org (email, password) values (?, ?) 
Hibernate: insert into org (email, password) values (?, ?) 
Hibernate: insert into org (email, password) values (?, ?) 
Hibernate: insert into user (email, password) values (?, ?) 
Hibernate: insert into user (email, password) values (?, ?) 
Hibernate: insert into UserSubscribes (userId, orgId) values (?, ?) 
Hibernate: insert into UserSubscribes (userId, orgId) values (?, ?) 
Hibernate: insert into UserSubscribes (userId, orgId) values (?, ?) 

和輸出

enter image description here

但在hibernate.cfg.xml文件中我不能沒有地圖從中檢索行(使用HQL)此表。
如果對這個問題有任何可能的解決方案,我真的很感謝你。 預先感謝您。

+0

可能重複的[HQL:與多對多休眠查詢](http://stackoverflow.com/questions/3475171/ hql-hibernate-query-with-manytomany) – herau

回答

1

連接表不應該被映射爲實體。您只需要這兩個實體之間的用戶,組織和ManyToMany關聯。

在那種我想創建模型類多對多的連接表從表中檢索行以檢查其組織由用戶訂閱

可與協會進行:

User user = em.find(User.class, userId); 
Set<Organization> organizations = user.getOrganizations(); 

或用一個簡單的JPQL查詢:

select o from User u inner join u.organizations o where u.id = :userId 
+0

我不知道什麼是em.find(User.class,userId)能否解釋它。順便說一句,我實現它使用session.get(User.class,userId),如我所回答的。謝謝@JBNizet – Piyush

+0

你用JPA標記了你的問題,所以我認爲你使用的是標準的JPA API(em是EntityManager)而不是舊的專有Hibernate API。 'em.find(User.class,userId)'和'session.get(User.class,userId)'做同樣的事情。 –

+0

好吧,我得到它'em.find(User.class,userId)'用於JPA,但現在我使用Hibernate API.Thanks Again :) – Piyush

0

Ť hanks JB Nizet

我按照你的建議實現代碼,它的工作非常完美。 這是解決的代碼。

GetSubscriber.java

package view.action; 

public class GetSubscriber extends ActionSupport { 

    public String execute(){ 

     Session session = HibernateUtill.getSessionFactory().getCurrentSession(); 
     session.beginTransaction(); 

     User u = (User) session.get(User.class, (long)1); 
     List<Organisation> s = (List<Organisation>) u.getOrgSubscribes(); 

     for(int i=0;i<s.size();i++){ 
      System.out.println(s.get(i).getOrgId() + " " + s.get(i).getEmail()); 
     } 

     return SUCCESS; 
    } 
} 

輸出:

1 ppp 
2 qqq 
3 www 
+0

'List s = new ArrayList ();'是無用的:你創建一個空的ArrayList,然後通過給's'分配另一個列表來立即忘掉它。所有你需要的是'List s = u.getOrgSubscribees();'。你不應該需要任何演員。 'u.getOrgSubscribees()'應該返回一個'List '。 –

+0

我更新了代碼。謝謝 – Piyush