2014-04-27 120 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