如何使用hibernate延迟加载可以为null的列

时间:2016-06-28 13:26:41

标签: java spring hibernate jpa spring-data-jpa

这是我的实体:

@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();

}

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

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

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

请帮帮我。

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

为什么要在此处编写自定义查询。你不需要。

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

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

此处JPA显示与User相关的所有信息。

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

答案 2 :(得分:0)

看起来您正在尝试使用预定义查询进行延迟加载,但我认为这不会起作用。

请参阅查询中的JOIN FETCH说明以下内容:

  

获取拥有u.City

的所有用户

因此,如果您没有为用户提供u.City,则返回将为空。

JoinFetch

上的更多info

您真正想要的是以下内容:

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,则会返回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