【问题标题】:hibernate select new object constructor休眠选择新对象构造函数
【发布时间】:2018-06-05 13:48:46
【问题描述】:

我目前正在使用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.classDTO:

@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)

请帮帮我,这个问题困扰我很久了。

【问题讨论】:

  • 请至少让人们有机会通过在多行上格式化您的代码来帮助您。这是不可读的。也与你的英语无关。
  • 请提供您的CustomerMaintain 班级。
  • @Alan 对不起,我已经完成了格式化。
  • @amir110 提供完毕,希望大家给点建议,谢谢。
  • 因为@ManyToOneUser,spring jpa 为用户刷新数据。看到这个链接stackoverflow.com/questions/20074881/additional-queries-in-jpa

标签: java hibernate jpa hql jpql


【解决方案1】:

您能解释一下为什么您认为需要NEW 运算符吗? c 的类型已经是CustomerMaintain,所以SELECT c 就足够了。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-31
    • 2013-04-24
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多