2016-06-28 7 views
1

Das ist meine Einheit:Wie mit Spalte verzögertes Laden überwintern verwenden, die null sein kann

@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; 
//... 

} 

In meinem Repository Ich habe:

public interface UserRepository extends JpaRepository<User, Long>{ 

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

} 

Wenn gibt es irgendwelche Städte in der Tabelle, findAllUserForApi() zeigt mir vollständige Informationen über Benutzer:

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

Wenn es keine Städte sind, ich zumindesterhalten möchten Aber ich habe nichts: []

Hilf mir bitte.

+0

Warum nicht einfach LEFT JOIN FETCH verwenden? – arturo

+0

Brilliant! Ich werde es als Antwort markieren. –

Antwort

3

Da Sie bereits eine benutzerdefinierte Abfrage verwenden, wäre die einfachste Lösung ein LEFT JOIN sein FETCH: @Query("SELECT u FROM User u LEFT JOIN FETCH u.city") So können alle Benutzer unabhängig von geladen werden, ob sie eine Stadt haben oder nicht ; und für diejenigen, die eine Stadt haben, wird es von user.getCity() zur Verfügung stehen.

1

Warum schreiben Sie benutzerdefinierte Abfrage hier. Du brauchst es nicht.

Erstens müssen Sie allgemeine Konvention folgen:

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

Und hier PPV zeigt alle Informationen mit Benutzern bezogen.

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

Weil ich nicht alle Spalten aus meiner Tabelle laden möchte. Ich habe mehr als diese. Auch ich habe Telefone, Adresse ... Und ich will sie in der Query-Antwort nicht sehen. –

+0

@ TomWally Wenn Sie nicht auf Ihrem JSON sehen möchten, können Sie Jsonignore Annotation Benutzer. Auf diese Weise können Sie bestimmte Attribute anzeigen. –

+0

Ja, aber JsonIgnore hat keine Optionen. Was, wenn ich einige Felder wie Passwort für Benutzer mit Priorität admin anzeigen möchte, aber nicht für Benutzer mit Prioritätsmoderator anzeigen möchte. JsonIgnore gibt mir keine Chance, diese Felder jemandem zu zeigen. –

0

Es sieht aus wie Sie Lazy Loading-zu verwenden, mit einer vordefinierten Abfrage versuchen, ich glaube nicht, das geht zu arbeiten.

See, die JOIN FETCH in Ihrer Anfrage Zustand folgenden:

alle Benutzer erhalten, die u.City hat

Also, wenn Sie nicht über ein u.City für einen Benutzer haben die Rückkehr wäre leer.

Mehr info auf Join und Fetch

Was Sie wirklich wollen, ist die folgende:

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; 
} 

Wenn der u.City ist NULL, wird es eine NULL zurück. während das User Objekt Daten enthält.

Oder in Ihrem Fall alle Benutzer finden:

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; 
} 

Hinweis: ich den Code nicht getestet, diese Pseudo ist, so dass Sie einen Teil davon ändern möchten.

source

+0

Danke dafür, aber LINKER JOIN FETCH war die richtige Antwort ( –

+0

@TomWally altough 'links join' wird funktionieren. Es ist nicht faul laden. Es ist nur eine benutzerdefinierte Abfrage. – Igoranze

Verwandte Themen