Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Hibernate和JPA触发意外查询_Java_Mysql_Hibernate_Jpa_Hql - Fatal编程技术网

Java 使用Hibernate和JPA触发意外查询

Java 使用Hibernate和JPA触发意外查询,java,mysql,hibernate,jpa,hql,Java,Mysql,Hibernate,Jpa,Hql,我已经编写了从DB获取数据的代码,但它也触发了一个意外的查询: @SuppressWarnings("unchecked") @Transactional public List<Job> getAppliedPositionsById(Long userId) { // String currentDate = SQLDateFormator.getCurrentDateInSqlFormat(); String strQuery = "f

我已经编写了从DB获取数据的代码,但它也触发了一个意外的查询:

@SuppressWarnings("unchecked")
    @Transactional
    public List<Job> getAppliedPositionsById(Long userId) {
//      String currentDate = SQLDateFormator.getCurrentDateInSqlFormat();
        String strQuery = "from Job x left join x.applications a where a.applicant.id = :userId";
        Query query = entityManager.createQuery(strQuery);
        query.setParameter("userId", userId);
        return query.getResultList();
    }
休眠:

    select
        job0_.id as id1_5_0_,
        applicatio1_.id as id1_1_1_,
        job0_.close_date as close_da2_5_0_,
        job0_.committee_chair_id as committe6_5_0_,
        job0_.description as descript3_5_0_,
        job0_.publish_date as publish_4_5_0_,
        job0_.title as title5_5_0_,
        applicatio1_.applicant_id as applican6_1_1_,
        applicatio1_.current_job_institution as current_2_1_1_,
        applicatio1_.current_job_title as current_3_1_1_,
        applicatio1_.current_job_year as current_4_1_1_,
        applicatio1_.cv_id as cv_id7_1_1_,
        applicatio1_.job_id as job_id8_1_1_,
        applicatio1_.research_statement_id as research9_1_1_,
        applicatio1_.submit_date as submit_d5_1_1_,
        applicatio1_.teaching_statement_id as teachin10_1_1_ 
    from
        jobs job0_ 
    left outer join
        applications applicatio1_ 
            on job0_.id=applicatio1_.job_id 
    where
        applicatio1_.applicant_id=?
    select
        user0_.id as id1_8_0_,
        user0_.address as address2_8_0_,
        user0_.email as email3_8_0_,
        user0_.first_name as first_na4_8_0_,
        user0_.last_name as last_nam5_8_0_,
        user0_.password as password6_8_0_,
        user0_.phone as phone7_8_0_ 
    from
        users user0_ 
    where
        user0_.id=?
Users
表的第二个查询完全没有必要

作业
实体

   @Id
    @GeneratedValue
    private Long id;

    private String title;

    private String description;

    @Column(name = "publish_date")
    private Date publishDate;

    @Column(name = "close_date")
    private Date closeDate;

    @ManyToOne
    @JoinColumn(name = "committee_chair_id")
    private User committeeChair;

    @ManyToMany
    @JoinTable(name = "job_committee_members",
        joinColumns = @JoinColumn(name = "job_id") ,
        inverseJoinColumns = @JoinColumn(name = "user_id") )
    @OrderBy("lastName asc")
    private List<User> committeeMembers;

    @OneToMany(mappedBy = "job")
    @OrderBy("date asc")
    private List<Application> applications;
}
用户
实体:

 @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private Job job;

    @ManyToOne
    private User applicant;

    @Column(name = "submit_date")
    private Date submitDate;

    @Column(name = "current_job_title")
    private String currentJobTitle;

    @Column(name = "current_job_institution")
    private String currentJobInstitution;

    @Column(name = "current_job_year")
    private Integer currentJobYear;

    @ElementCollection
    @CollectionTable(name = "application_degrees",
        joinColumns = @JoinColumn(name = "application_id") )
    @OrderBy("year desc")
    private List<Degree> degrees;

    @OneToOne
    private File cv;

    @OneToOne
    @JoinColumn(name = "research_statement_id")
    private File researchStatement;

    @OneToOne
    @JoinColumn(name = "teaching_statement_id")
    private File teachingStatement;

    @OneToMany(mappedBy = "application",
        cascade = { CascadeType.MERGE, CascadeType.PERSIST })
    @OrderColumn(name = "round_index")
    private List<Round> rounds;
}
@Id
    @GeneratedValue
    private Long id;

    @Column(unique = true, nullable = false)
    private String email;

    @Column(nullable = false)
    private String password;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    private String address;

    private String phone;

    @OneToMany(mappedBy = "applicant")
    @OrderBy("id desc")
    private List<Application> applications;
}
@Id
@生成值
私人长id;
@列(unique=true,nullable=false)
私人字符串电子邮件;
@列(nullable=false)
私有字符串密码;
@列(name=“first_name”)
私有字符串名;
@列(name=“last_name”)
私有字符串lastName;
私有字符串地址;
私人电话;
@OneToMany(mappedBy=“申请人”)
@订购人(“id描述”)
私人名单申请;
}

根据JPA 2.0规范,默认设置如下:

一个女人:懒惰

曼尼通:渴望

很多人:懒惰

渴望

您在应用程序类中有

@ManyToOne
private User applicant;
如果你换成懒惰

@ManyToOne(fetch = FetchType.LAZY)

它应该按照您想要的方式工作。

正如luksch所指出的,您的模型定义了一个与用户的
@manytone
关系,默认情况下,每次加载作业实例(或模型中的应用程序实例)时都会热切地获取该关系。 但是,现在切换它
FetchType.LAZY
可能会产生预期的结果。使用oneToOne或manyToOne,hibernate将不得不进行额外的查询,即使它是懒惰的。只有在指定关系的
optional=false
属性以及
FetchType.LAZY
时,它才会自动将代理对象设置为用户属性的值。这是因为Hibernate在检查数据库之前无法知道用户属性是否存在或为null。 根据您的模型,更合适的解决方案是更新查询以在一个查询中获取用户对象,如下所示:

String strQuery = "from Job x left join fetch x.committeeChair u left join x.applications a where a.applicant.id = :userId"
重要的部分是left join fetch x.committeeChair u,它告诉hibernate添加额外的连接并获取相关对象

这修复了使用JPQL获取作业实例时的行为。 如果您试图通过
EntityManager.find
方法按其id加载单个作业实例。它仍然会为用户committeeChair生成一个额外的查询。您可以通过使用来进一步优化加载策略 请注意,获取模式可能会禁用可能不需要的延迟加载。 我建议您首先确定需要加载哪些数据、始终存在哪些数据,并根据这些数据优化您的查询。通常,一个额外的查询比在一个查询中加载整个实体图要好。
祝你好运

你能将hibernate注释发布到相关类(用户、应用程序、作业)的相关部分吗?我更新了问题。在作业实体中,尝试@manytone(fetch=FetchType.LAZY)private User committeeChair;解释得很好!虽然我很喜欢JPA和Hibernate,但最终我发现自己又重新优化hql或criteria查询,以准确获取所需内容,然后处理会话范围之外的对象。。。