已经在google上研究过这个问题,看起来我的代码中存在一切,但代码中仍然存在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;
}
}
TestingHibernate.java(带主要的类)
public class TestingHibernate {
public static void main(String[] args) {
HibernateUtils.initSessionFactory();
List<User> users = new ArrayList<>();
UserDao uDao1 = new UserDao();
users = uDao1.getAllUsers();
ListIterator i = users.listIterator();
while (i.hasNext()) {
User u = (User) i.next();
System.out.println(u.getFirstName() + " " + u.getLastName());
}
HibernateUtils.getSessionFactory().close();
}
}
输出:
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
看起来Fetch Mode JOIN也正常工作但我仍然有三个选择用于子表,当用户更多时会占用大量资源。 我可能会犯一个非常愚蠢的错误,但仍然想要更多的眼睛来调查,以便找到错误。