Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何对可以为null的列使用hibernate延迟加载_Java_Spring_Hibernate_Jpa_Spring Data Jpa - Fatal编程技术网

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

Java 如何对可以为null的列使用hibernate延迟加载,java,spring,hibernate,jpa,spring-data-jpa,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 =

这是我的实体:

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

}
如果没有城市,我想得到至少
[{“id”:1,“name”:“John”,“姓氏”:“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();
}
public interface UserRepository扩展了JpaRepository{
公共列表findAll();
}

看起来您试图对预定义查询使用延迟加载,我认为这行不通

请参阅,查询中的
连接获取
状态如下:

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.City的用户

因此,如果您没有用户的
u.City
,则返回值将为空

有关
Join
Fetch

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

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.City
NULL
,它将返回
NULL
。而
用户
对象包含数据

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

公共列表findUserByID(长用户ID)
{
Session Session=sessionFactory.getCurrentSession();
List users=(List)session.createCriteria(User.class);
//这将强制SQL执行查询,该查询将与用户的城市连接并填充
//将适当的信息导入用户对象。
for(用户:用户)
初始化(user.geCity());
返回用户;
}  
注意: 我没有测试代码,这是伪代码,因此您可能需要对其进行一些更改


鉴于您已经在使用自定义查询,最简单的解决方案是左连接获取:

@查询(“从用户u中选择u左加入获取u.city”)

这样,所有用户都将被加载,无论他们是否拥有城市;对于那些拥有城市的用户,
user.getCity()

因为我不想从表中加载所有列。我有更多的列。我还有电话、地址……我不想在查询答案中看到它们。@TomWally如果你不想在json上看到,你可以使用Jsonignore注释。这样你可以显示特定的属性。是的,但Jsonignore没有选项。如果我想不想为具有优先级管理员的用户显示某些字段,如密码,但不想为具有优先级版主的用户显示。JsonIgnore没有给我机会向任何人显示这些字段。也许你可以尝试额外的DTO对象,并为每个用户标题分别显示属性。如果它看不到你的业务,当你返回类似密码的属性时,你可以n将它们设置为空。为什么不简单地使用左连接获取?太棒了!我会将其标记为答案。谢谢您,但左连接获取是正确的答案(@TomWally although'LEFT JOIN'将起作用。它不是延迟加载。它只是一个自定义查询。
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;  
}