L'EntityManager.trouver ne pouvez pas trouver de l'entité, mais à l'aide de l'API criteria n'
J'ai rencontré un cas assez curieux dans Java EE 6, où à l'aide de l'EntityManager est find
méthode avec une entité primaire id renvoie null, mais à l'aide de l'API des Critères pour sélectionner toutes les entités id fonctionne très bien.
Voici le code que j'utilise pour find
:
//Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);
...et voici le code que j'utilise avec les Critères de l'API:
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();
Aucune idée pourquoi find
retourne null mais les Critères trouve l'Utilisateur? J'ai essayé ces deux méthodes de rechange dans la même place dans le programme.
Voici les parties pertinentes de l'entité Utilisateur:
@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;
}
...
}
Vous ne savez pas si cela fait une différence, mais est userId un Long ou peut-être un nombre Entier dans votre code?
C'est une Longue, j'ai vérifié que.
J'ai juste rencontré ce problème avec Hibernate 4.1.8.Final
C'est une Longue, j'ai vérifié que.
J'ai juste rencontré ce problème avec Hibernate 4.1.8.Final
OriginalL'auteur cdmckay | 2010-07-08
Vous devez vous connecter pour publier un commentaire.
J'ai compris le problème. Elle est due à un champ dans la base de données
null
où il ne doit pas avoir été autorisé. Cela était dû à moi de montage à la main. Après j'ai ajouté une valeur à ce champ, le problème a disparu.vive le partage, a sauvé ma journée
100% d'accord. Ce n'était pas ma base de données, mais il m'a appris la valeur de l'utilisation de contraintes à respecter l'intégrité des données 😉
Mon pari est que trouver tente d'obtenir l'entité à l'aide de jointures internes, car cela peut provoquer vide jeux de résultats
OriginalL'auteur cdmckay
Ce fournisseur que vous utilisez?
Où en êtes-vous de l'exécution de cette trouvaille, dans ou en dehors d'une transaction? Êtes-vous le rinçage et la compensation de l'EM avant de le trouver?
À l'aide de EclipseLink en tant que fournisseur, et mon propre modèle similaire, je ne suis pas en mesure de reproduire ce.
En supposant que le fournisseur peut se connecter à SQL, voyez-vous SQL aller à la DB sur de la trouver? Quel est le SQL ressembler, et il le fait exécuter correctement dans SQL Plus etc...
Je suis en cours d'exécution dans un
@Stateless
EJB. L'EM est décoré avec un@PersistanceContext(unitName = "xxx_persistence")
. Je vais consulter les journaux SQL et voir ce que je peux trouver.Ok j'ai vérifié le SQL et a été très surpris de voir la différence entre les deux requêtes: le "trouver" version était en train de faire un milliard rejoint alors que les "critères" de la requête a été extrait uniquement à partir de la table des utilisateurs. Quelqu'un d'autre a écrit l'entité fichiers donc je vais devoir creuser par le biais de ces personnes à trouver la cause de cette.
"je devrais être rinçage à l'EM avant de le trouver? Je suis de l'utilisation d'Hibernate comme mon fournisseur." N (l'exécution d'une requête se rincer les modifications en attente).
OriginalL'auteur Peter Krogh
Je confirme la solution. La même chose m'est arrivé. J'ai eu colonnes marquées comme
NOT NULL
, puis lors des essais dans mon application, j'ai changé la limitation off dans la base de données pour les deux colonnes (clés étrangères), mais de ne pas changer l' (optional = false
) attribut de@ManyToOne
relation dans ma classe d'entité. Après la suppression de l'attribut, de sorte que le modèle est compatible avec la base de données, tout a commencé à bien fonctionner.Étrange que l'environnement ne produisent pas d'un avertissement ou d'une exception quelconque.
OriginalL'auteur pkudlacik
Vérifiez que vous êtes de passage à un
Long
dans l'extrait suivant:Si cela ne vous aide pas, activer la journalisation SQL pour voir ce qui se passe et de comparer le comportement dans les deux cas.
J'ai couru votre code de mon côté et je ne peux pas reproduire (comme prévu pour être honnête). Testé avec Hibernate EM 3.5.3-Finale.
Ouais, je pense que cela a à voir avec la façon dont l'entité Utilisateur est annoté.
OriginalL'auteur Pascal Thivent
L'une des raisons pourrait être que le champ "id" n'a pas été correctement marqués comme étant l'id de l'entité Utilisateur.
OriginalL'auteur bashflyng
Comme un test de cohérence déboguer votre code, en prenant le temps avant l'exécution de la trouver pour exécuter un manuel de requête sur la base de données vous-même de s'assurer qu'un enregistrement de l'Utilisateur est présent avec l'id que vous attendez.
Si ce n'est pas dans la base de données, s'assurer que le gestionnaire de l'entité a été vidées ou la transaction en cours a été commis.
Par exemple, si vous êtes en utilisant Hibernate en tant que fournisseur, il est possible que l'objet est "persistantes" simplement en cache et les modifications n'ont pas réellement été poussé à la base de données. En conséquence, les critères de passer par Hibernate mise en œuvre permettra de récupérer l'objet, mais le gestionnaire d'entité trouver ne sera pas en mesure de localiser l'objet.
OriginalL'auteur apiri