2016-06-28 2 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; 
//... 

} 

В моей Repository у меня есть:

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] Но у меня ничего нет: []

Помогите мне пожалуйста.

+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 нет вариантов. Что делать, если я хочу показать некоторые поля, такие как пароль для пользователя с приоритетом admin, но не хочу показывать для пользователей с модератором приоритета. JsonIgnore не дает мне возможности показать эти поля никому. –

0

Похоже, что вы пытаетесь использовать отложенную загрузку с предопределенным запросом, я не думаю, что это будет работать.

Престола, JOIN FETCH в вашем состоянии запроса следующее:

Получить все пользователи, которые имеет u.City

Так что, если вы не имеете u.City для пользователя, return будет пустым.

info Больше на 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. а объект 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 altough 'left join' будет работать. Это не ленивая загрузка. Это просто пользовательский запрос. – Igoranze

Смежные вопросы