使用带有Hibernate Criteria API的未映射属性通过子表连接两个父表

时间:2015-02-20 12:09:49

标签: java hibernate join many-to-many hibernate-criteria

我有以下模型

| user      | usercustomer  | customer
| id        | user_id       | id
| username  | customer_id   | customernumber

如果可能,我想通过使用Hibernate Criteria API来完成以下查询:

SELECT customer.* 
FROM customer
JOIN usercustomer ON customer.id = usercustomer.customer_id
JOIN user ON user.id = usercustomer.user_id
WHERE user.username = 'xxxx';

User.class

@Entity
@Table
public class User {
    private Integer id;
    private String username;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer getId(){
        return id;
    }

    public void setId(Integer id){
        this.id = id;
    }

    @Column(nullable = false, unique = true, length = 50)
    public String getUsername(){
        return username;
    }

    public void setUsername(String username){
        this.username = username;
    }
}

Customer.class

@Entity
public class Customer {
    private Integer id;
    private String customerNumber;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer getId(){
        return id;
    }

    public void setId(Integer id){
        this.id = id;
    }

    @Column(unique = true, nullable = false, length = 50)
    public String getCustomerNumber(){
        return customerNumber;
    }

    public void setCustomerNumber(String customerNumber){
        this.customerNumber = customerNumber;
    }

    @OneToMany(mappedBy = "userCustomerPrimaryKey.customer", cascade = { CascadeType.REMOVE })
    public List<UserCustomer> getUserCustomers(){
        if(userCustomers == null){
            userCustomers = new ArrayList<UserCustomer>();
        }
        return userCustomers;
    }

    public void setUserCustomers(List<UserCustomer> userCustomers){
        this.userCustomers = userCustomers;
    }

}

UserCustomer.class

@Entity
public class UserCustomer {
    private UserCustomerPrimaryKey userCustomerPrimaryKey;

    @EmbeddedId
    private UserCustomerPrimaryKey getUserCustomerPrimaryKey(){
        if(userCustomerPrimaryKey == null){
            userCustomerPrimaryKey = new UserCustomerPrimaryKey();
        }
        return userCustomerPrimaryKey;
    }

    protected void setUserCustomerPrimaryKey(UserCustomerPrimaryKey userCustomerPrimaryKey){
        this.userCustomerPrimaryKey = userCustomerPrimaryKey;
    }

    @Transient
    public User getUser(){
        return getUserCustomerPrimaryKey().getUser();
    }

    public void setUser(User user){
        getUserCustomerPrimaryKey().setUser(user);
    }

    @Transient
    public Customer getCustomer(){
        return getUserCustomerPrimaryKey().getCustomer();
    }

    public void setCustomer(Customer customer){
        getUserCustomerPrimaryKey().setCustomer(customer);
    }

    @Embeddable
    public static class UserCustomerPrimaryKey implements Serializable {
        private User user;
        private Customer customer;

        @ManyToOne(optional = false)
        @JoinColumn(name = "user_id")
        public User getUser(){
            return user;
        }

        public void setUser(User user){
            this.user = user;
        }

        @ManyToOne(optional = false)
        @JoinColumn(name = "customer_id")
        public Customer getCustomer(){
            return customer;
        }

        public void setCustomer(Customer customer){
            this.customer = customer;
        }
    }
}

如果我已经有用户ID,那么我可以这样打电话(这样可以正常工作):

Criteria customerCriteria = getSession().createCriteria(Customer.class);
Criteria userCustomerCriteria = customerCriteria.createCriteria("userCustomers");
Disjunction junction = Restrictions.disjunction();
junction.add(Restrictions.eq("userCustomerPrimaryKey.user.id", user.getId()));
userCustomerCriteria.add(junction);

但我想要完成的是:

Criteria customerCriteria = getSession().createCriteria(Customer.class);
Criteria userCustomerCriteria = customerCriteria.createCriteria("userCustomers");
Disjunction junction = Restrictions.disjunction();
junction.add(Restrictions.eq("userCustomerPrimaryKey.user.username", user.getUsername()));
userCustomerCriteria.add(junction);

如果我运行它会出现以下错误:

org.hibernate.QueryException: could not resolve property: 
userCustomerPrimaryKey.user.username of: UserCustomer

我也试过

Criteria customerCriteria = getSession().createCriteria(Customer.class);
Criteria userCustomerCriteria = customerCriteria.createCriteria("userCustomers");
userCustomerCriteria.createAlias("userCustomerPrimaryKey.user", "u").add(Restrictions.eq("u.username", user.getUsername()));

哪个给出了

2015-02-20 12:52:30 ERROR JDBCExceptionReporter.java:101  Column not found: U2_.USERNAME in statement 
[SELECT 
...fields truncated...
usercustom1_.customer_id AS customer1_47_0_, 
usercustom1_.user_id AS user2_47_0_ 
FROM customer this_ 
inner join usercustomer usercustom1_ ON this_.id=usercustom1_.customer_id 
where u2_.username=? order by this_.id ASc]

编辑还通过userCustomerPrimaryKey明确加入:

Criteria customerCriteria = getSession().createCriteria(Customer.class);
Criteria userCustomerCriteria = customerCriteria.createCriteria("userCustomers");
Criteria userCriteria = userCustomerCriteria.createCriteria("userCustomerPrimaryKey.user");
userCriteria.add(Restrictions.eq("username", user.getUsername()));

给出了:

2015-02-20 14:30:29 ERROR JDBCExceptionReporter.java:101  
Column not found: USER2_.USERNAME in statement 
[select 
... fields truncated ...
from customer this_ 
inner join usercustomer usercustom1_ on this_.id=usercustom1_.customer_id 
where user2_.username=? order by this_.id asc]

我怎样才能做到这一点或者这是不可能的?

0 个答案:

没有答案