2016-06-28 42 views
1

这是我的实体:如何使用休眠模式,列延迟加载,可以为空

@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()节目me关于用户的全部信息:

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

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

请帮助我。

+0

为什么不简单地使用LEFT JOIN FETCH? – arturo

+0

辉煌!我会将其标记为答案。 –

回答

3

既然你已经使用了自定义查询,最简单的解决方案将是一个LEFT JOIN FETCH @Query("SELECT u FROM User u LEFT JOIN FETCH u.city") 这样,所有用户将不管他们是否有一个城市或没有加载;对于那些有城市的人来说,它可以通过user.getCity()获得。

1

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

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

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

因为我不想加载我的表中的所有列。我比这更多。我也有电话,地址......而且我不想在查询答案中看到他们。 –

+0

@TomWally如果你不想看到你的JSON,你可以使用Jsonignore注释。这样你可以显示特定的属性。 –

+0

是的,但JsonIgnore没有选项。如果我想为优先级管理员显示一些类似密码的字段,但不想显示给具有优先级管理员的用户。 JsonIgnore并没有给我一个向任何人展示这个领域的机会。 –

0

它看起来像你试图使用惰性加载与预定义的查询,我不认为这将工作。

看到,查询状态JOIN FETCH如下:

取得与u.City

所以所有用户,如果你没有为用户u.City呢,返回将是空的。

更多infoJoinFetch

你真正想要的是以下几点:

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

+0

感谢您的支持,但是LEFT JOIN FETCH是正确的答案( –

+0

@TomWally尽管'left join'可以工作,但不是延迟加载,它只是一个自定义查询。 – Igoranze