Java 休眠:n+;1查询问题&x2013;OneTONE协会
我已经在谷歌上研究过这个问题,看起来我的代码中包含了所有内容,但代码中仍然存在n+1查询问题。尝试了所有可用的建议/解决方法,但每次都得到了相同的结果。请告诉我哪里出了问题 下面只是一个示例(存在n+1问题的工作代码) User.javaJava 休眠: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
@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