如何对可以为空的列使用休眠延迟加载

How to use hibernate lazy loading with column that can be null

这是我的实体:

@Entity
@Table(name = "users")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

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

@Column(name = "surname")
private String surname;


@ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.MERGE)
@JoinColumn(name = "id_city")
private City city;
//...

}

在我的存储库中我有:

public interface UserRepository extends JpaRepository<User, Long>{

@Query("SELECT u FROM User u JOIN FETCH u.city")
public List<User> findAllUserForApi();

}

如果 table 中有任何城市,findAllUserForApi() 会显示有关用户的完整信息:

[{"id":1,"name":"John","surname":"Pillman","city":{"id":1,"name":"New York"}]

如果没有城市,我想至少得到[{"id":1,"name":"John","surname":"Pillman","city":null] 但是我什么都没有:[]

请帮帮我。

为什么要在这里写自定义查询。你不需要。

首先你必须遵循一般惯例:

@ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.MERGE)
@JoinColumn(name = "CITY_ID")
private City city;
...

这里JPA显示了与用户相关的所有信息。

public interface UserRepository extends JpaRepository<User, Long>{
    public List<User> findAll();
}

您似乎在尝试对预定义查询使用延迟加载,我认为这不会奏效。

请看,您查询中的 JOIN FETCH 状态如下:

Get all the Users which has u.City

因此,如果您没有用户的 u.City,return 将为空。

更多 info JoinFetch

你真正想要的是:

public User findUserByID(Long userId)
{
    Session session = sessionFactory.getCurrentSession();  

    User user = (Users) session.createCriteria(User.class).add(Restrictions.idEq(userId)).uniqueResult();  

    // this will force SQL to execute the query that will join with the user's city and populate  
    //  the appropriate information into the user object.  
    Hibernate.initialize(user.geCity());  

    return user;  
}  

如果u.CityNULL,它将return一个NULL。而 User 对象包含数据。

或者您的情况 查找所有用户 :

public List<User> findUserByID(Long userId)
{
    Session session = sessionFactory.getCurrentSession();  

    List<User> users = (List<User>) session.createCriteria(User.class);

    // this will force SQL to execute the query that will join with the user's city and populate  
    //  the appropriate information into the user object.  

    for (User user : users)
        Hibernate.initialize(user.geCity());  

    return user;  
}  

注意: 我没有测试代码,这是伪代码,因此您可能需要更改其中的一些内容。

source

鉴于您已经在使用自定义查询,最简单的解决方案是 LEFT JOIN FETCH @Query("SELECT u FROM User u LEFT JOIN FETCH u.city") 这样无论有没有城市,所有用户都会被加载;对于那些拥有城市的人,它将在 user.getCity().

之前提供