hibernate选择新的对象构造函数

时间:2017-12-23 03:13:45

标签: java hibernate jpa hql jpql

我目前正在使用JPA开发项目,但遇到了问题,请指教

示例:

@Query("
    SELECT 
        new CustomerMaintain(c.content, u, c.createTime, c.updateTime) 
    FROM 
        CustomerMaintain c 
    JOIN 
        c.user u
    WHERE 
        c.delFlag = FALSE AND c.customer.id = :customerId
")

CustomerMaintain.class DTO:

@Entity
@Table(name = "t_customer_maintain")
@DynamicUpdate
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "delFlag"})
public class CustomerMaintain {

    public CustomerMaintain() {
    }

    public CustomerMaintain(String content, User user, Date createTime, Date updateTime) {
        this.content = content;
        this.user = user;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(columnDefinition = "VARCHAR(512) DEFAULT ''")
    private String content;

    @ManyToOne(optional=false)
    private User user;

    @ManyToOne(optional=false)
    private Customer customer;

    @Column(columnDefinition = "TINYINT(1) DEFAULT FALSE ",insertable = false,updatable = false)
    private Boolean delFlag;

    @Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP",insertable = false,updatable = false)
    private Date createTime;

    @Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP",insertable = false,updatable = false)
    private Date updateTime;

    // omission getter setter method

}

我认为只有一个SQL查询:

SELECT 
    c.content, 
    u.id, 
    u.name, 
    u.head, 
    c.createTime, 
    c.updateTime
FROM 
    t_customerMaintain c 
INNER JOIN 
    t_user u ...

但是hibernate查询结果是这样的:

select 
    customerma0_.content as col_0_0_, 
    user1_.id as col_1_0_, /* only user.id fields */
    customerma0_.createTime as col_2_0_,
    customerma0_.updateTime as col_3_0_
from 
    t_customer_maintain customerma0_
inner join 
    t_user user1_ 
...

select 
    user0_.id as id1_4_0_,  
    user0_.head as head4_4_0_,
    user0_.name as name5_4_0_ 
from 
    t_user user0_ 
where 
    user0_.id=? /* user1_.id as col_1_0_ */

问题:

为什么第一个SQL查询只有user.id,而不是user.iduser.nameuser.head

最后一个SQL查询是多余的。

我试着这样写:

SELECT 
    new CustomerMaintain(c.content, new User(u.id, u.name, u.head), c.createTime, c.updateTime) 

但这样做会引发异常:new User(u.id, u.name, u.head)

请帮助我,这个问题一直困扰着我很久。

1 个答案:

答案 0 :(得分:0)

你能解释为什么你认为你需要NEW运算符吗? c的类型已经CustomerMaintain,因此SELECT c就足够了。

如果您想明确提取User,请使用JOIN FETCH代替JOIN。这样,User的额外查询将不会被执行。或者,您可以使用Hibernate的@Fetch(FetchMode.JOIN)强制Hibernate使用连接查询(而不是单独的选择查询)在需要时加载CustomerMaintain.user

如果您需要更精细地控制在查询结果中填充哪些属性,请使用获取图或加载图作为查询提示。 不要NEW与实体构造函数一起使用,因为从此类查询返回的结果将变为托管。