Frage

Ich bin in Java EE 6 auf einen ziemlich seltsamen Fall gestoßen, bei dem die JPA-EntityManager verwendet wurden find -Methode zusammen mit der primären ID einer Entität gibt null zurück, aber die Verwendung der Kriterien-API zum Auswählen aller Entitäten mit dieser ID funktioniert einwandfrei.

Hier ist der Code, den ich verwende find:

// Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);

...und hier ist der Code, den ich mit der Criteria API verwende:

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> u = criteria.from(User.class);
TypedQuery<User> query = em.createQuery(
    criteria.select(u).where(builder.equal(u.get("id"), userId)));
user = query.getSingleResult();

Irgendeine Idee warum find Gibt null zurück, aber Criteria findet den Benutzer?Ich habe diese beiden alternativen Methoden an genau derselben Stelle im Programm ausprobiert.

Hier sind die relevanten Teile der Benutzerentität:

@Entity
@Table(name = "USERS")
@Access(AccessType.PROPERTY)
public class User implements Serializable {
    ...
    private Long id;
    ...
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_generator")
    @SequenceGenerator(name = "user_id_generator", sequenceName = "user_sequence", allocationSize = 1)
    @Column(name="id")
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    ...
}
War es hilfreich?

Lösung

Ich habe das Problem herausgefunden.Es lag an einem Feld in der Datenbank null wo es nicht hätte erlaubt sein dürfen.Das lag daran, dass ich es von Hand bearbeitet habe.Nachdem ich diesem Feld einen Wert hinzugefügt hatte, verschwand das Problem.

Andere Tipps

Welchen Anbieter nutzen Sie?

Wo führen Sie diese Suche aus, innerhalb oder außerhalb einer Transaktion?Spülen und reinigen Sie den EM vor dem Fund?

Wenn ich EclipseLink als Anbieter und mein eigenes ähnliches Modell verwende, kann ich dies nicht reproduzieren.

Angenommen, Ihr Anbieter kann SQL protokollieren. Sehen Sie dann, dass SQL bei der Suche in die Datenbank geht?Wie sieht SQL aus und wird es in SQL Plus usw. ordnungsgemäß ausgeführt?

Ich bestätige die Lösung.Mir geht es genauso.Ich hatte Spalten markiert als NOT NULL, dann habe ich während des Tests in meiner App die Beschränkung in der Datenbank für zwei Spalten (Fremdschlüssel) ausgeschaltet, die (optional = false) Attribut von @ManyToOne Beziehung in meiner Entitätsklasse.Nach dem Löschen des Attributs, damit das Modell mit der Datenbank übereinstimmte, begann alles einwandfrei zu funktionieren.Seltsam, dass die Umgebung keine Warnung oder Ausnahme erzeugt.

Überprüfen Sie noch einmal, ob Sie a bestehen Long im folgenden Ausschnitt:

// Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);

Wenn dies nicht hilft, aktivieren Sie die SQL-Protokollierung, um zu sehen, was passiert, und vergleichen Sie das Verhalten in beiden Fällen.

Ein Grund könnte sein, dass das Feld „id“ nicht korrekt als ID für die Benutzerentität markiert wurde.

Als Plausibilitätsprüfung debuggen Sie Ihren Code und nehmen sich vor der Ausführung der Suche die Zeit, selbst eine manuelle Abfrage in der Datenbank durchzuführen, um sicherzustellen, dass ein geeigneter Benutzerdatensatz mit der erwarteten ID vorhanden ist.

Wenn es nicht in der Datenbank vorhanden ist, stellen Sie sicher, dass der Entitätsmanager geleert wurde oder die aktuelle Transaktion festgeschrieben wurde.

Wenn Sie beispielsweise Hibernate als Anbieter verwenden, ist es möglich, dass das Objekt nur im Cache „persistent“ bleibt und die Änderungen nicht tatsächlich in die Datenbank übertragen wurden.Dementsprechend rufen die Kriterien, die die Hibernate-Implementierung durchlaufen, das Objekt ab, der Entitätsmanager find kann das Objekt jedoch nicht finden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top