Java 休眠:n+;1查询问题&x2013;OneTONE协会

Java 休眠:n+;1查询问题&x2013;OneTONE协会,java,hibernate,orm,Java,Hibernate,Orm,我已经在谷歌上研究过这个问题,看起来我的代码中包含了所有内容,但代码中仍然存在n+1查询问题。尝试了所有可用的建议/解决方法,但每次都得到了相同的结果。请告诉我哪里出了问题 下面只是一个示例(存在n+1问题的工作代码) User.java @Entity @Table(name = "USER_DETAILS") public class User implements Serializable { private int userId; private String firs

我已经在谷歌上研究过这个问题,看起来我的代码中包含了所有内容,但代码中仍然存在n+1查询问题。尝试了所有可用的建议/解决方法,但每次都得到了相同的结果。请告诉我哪里出了问题

下面只是一个示例(存在n+1问题的工作代码)

User.java

@Entity
@Table(name = "USER_DETAILS")
public class User implements Serializable {

    private int userId;
    private String firstName;
    private String lastName;
    private UserLvl userLvl;

    public User() {
    }

    public User(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "USERID")
    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    @Column(name = "FIRST_NAME", length = 50, nullable = false)
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Column(name = "LAST_NAME", length = 50, nullable = false)
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL)
    @Fetch(FetchMode.JOIN)
    public UserLvl getUserLvl() {
        return userLvl;
    }

    public void setUserLvl(UserLvl userLvl) {
        this.userLvl = userLvl;
    }

}
UserLvl.java

@Entity
@Table(name = "USER_LEVEL")
public class UserLvl implements Serializable {

    private User user;
    private String lvl;

    public UserLvl() {
    }

    public UserLvl(User user, String lvl) {
        this.user = user;
        this.lvl = lvl;
    }

    @Id
    @OneToOne
    @JoinColumn(name = "USERID")
    public User getUser() {
        return user;
    }

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

    @Column(name = "USER_LVL", length = 10)
    public String getLvl() {
        return lvl;
    }

    public void setLvl(String lvl) {
        this.lvl = lvl;
    }

}
UserDao.java

public class UserDao {

    public void addUser(User user) {
        Transaction tx = null;
        Session session = HibernateUtils.getSessionFactory().openSession();

        try {
            tx = session.beginTransaction();
            session.save(user);
            tx.commit();
        } catch (Exception e) {
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            session.close();
        }
    }

    public List<User> getAllUsers() {
        List<User> users = new ArrayList();

        Transaction tx = null;
        Session session = HibernateUtils.getSessionFactory().openSession();

        try {
            tx = session.beginTransaction();
            Criteria criteria = session.createCriteria(User.class);
            users = criteria.list();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (tx != null) {
                tx.commit();
            }
            session.close();
        }

        return users;
    }

}
数据库中的数据:

Table: USER_DETAILS
---------------------------------
USERID | FIRST_NAME | LAST_NAME | 
---------------------------------
1      | Person     | One
2      | Person     | Two
3      | Person     | Three


Table: USER_LEVEL
-----------------
USERID | USER_LVL 
-----------------
1      | Level1
2      | Level2
3      | Level3
看起来Fetch模式联接也正常工作,但我仍然为子表选择了三个选项,当用户更多时,这将占用大量资源。
我可能犯了一个非常愚蠢的错误,但仍然希望再多看几眼,这样才能发现错误。

您是否尝试过
criteria.setResultTransformer(criteria.DISTINCT\u ROOT\u ENTITY)?是的,Apostolos,像这样尝试过。。。但是相同的结果tx=session.beginTransaction();条件=session.createCriteria(User.class);criteria.setResultTransformer(criteria.DISTINCT\u ROOT\u实体);users=criteria.list()@Manoj,你能找到解决办法吗?在我的例子中,甚至连OneToOne字段的join fetch都不起作用……您是否尝试过
criteria.setResultTransformer(criteria.DISTINCT\u ROOT\u ENTITY)?是的,Apostolos,像这样尝试过。。。但是相同的结果tx=session.beginTransaction();条件=session.createCriteria(User.class);criteria.setResultTransformer(criteria.DISTINCT\u ROOT\u实体);users=criteria.list()@Manoj,你能找到解决办法吗?在我的情况下,即使是使用OneToOne字段连接fetch也不起作用。。。
Hibernate Session Factory is created

Hibernate: 
    /* criteria query */ select
        this_.USERID as USERID1_0_1_,
        this_.FIRST_NAME as FIRST_NA2_0_1_,
        this_.LAST_NAME as LAST_NAM3_0_1_,
        userlvl2_.USERID as USERID2_1_0_,
        userlvl2_.USER_LVL as USER_LVL1_1_0_ 
    from
        USER_DETAILS this_ 
    left outer join
        USER_LEVEL userlvl2_ 
            on this_.USERID=userlvl2_.USERID

Hibernate: 
    select
        userlvl0_.USERID as USERID2_1_0_,
        userlvl0_.USER_LVL as USER_LVL1_1_0_ 
    from
        USER_LEVEL userlvl0_ 
    where
        userlvl0_.USERID=?

Hibernate: 
    select
        userlvl0_.USERID as USERID2_1_0_,
        userlvl0_.USER_LVL as USER_LVL1_1_0_ 
    from
        USER_LEVEL userlvl0_ 
    where
        userlvl0_.USERID=?

Hibernate: 
    select
        userlvl0_.USERID as USERID2_1_0_,
        userlvl0_.USER_LVL as USER_LVL1_1_0_ 
    from
        USER_LEVEL userlvl0_ 
    where
        userlvl0_.USERID=?

Person One
Person Two
Person Three
Table: USER_DETAILS
---------------------------------
USERID | FIRST_NAME | LAST_NAME | 
---------------------------------
1      | Person     | One
2      | Person     | Two
3      | Person     | Three


Table: USER_LEVEL
-----------------
USERID | USER_LVL 
-----------------
1      | Level1
2      | Level2
3      | Level3