2010-05-17 2 views
25

J'utilise Hibernate et obtenir« Aucune ligne avec l'identifiant donné existe » bien qu'il n'existe

Exception dans le thread « principal » org.hibernate.ObjectNotFoundException: Aucune ligne avec l'identifiant donné existe: [# 271]

Ce qui est assez étrange à propos de cette erreur est que l'objet avec l'ID donné existe dans la base de données. J'ai inséré l'enregistrement problématique dans une autre exécution de l'application. Si j'y accède dans le même cycle (c'est-à-dire la même session d'hibernation), il ne semble pas y avoir de problèmes pour récupérer les données.

Tout simplement parce que cela pourrait être une faute de la mise en correspondance:

public class ProblemClass implements Persistent { 
    @ManyToOne(optional = false) 
    private MyDbObject myDbObject; 
} 
public class MyDbObject implements Persistent { 
    @OneToMany(mappedBy = "myDbObject") 
    private List<ProblemClass> problemClasses; 
    @ManyToOne(optional = false) 
    private ThirdClass thirdClass; 
} 

Je n'ai absolument aucune idée même où regarder. Des indices très appréciés!

Juste pour clarifier: Les données ont été insérées dans un autre RUN de l'application. Il est définitivement dans la base de données, comme je peux le voir via une requête SQL après la fin de l'application. Et après cela, c'est-à-dire lors du démarrage de l'application à nouveau, j'obtiens l'erreur dans la requête FIRST de la base de données - pas de suppression, pas de retour en arrière impliqué.

Addition: Parce qu'il a été demandé, voici le code pour récupérer les données:

public List<ProblemClass> getProblemClasses() { 
    Query query = session.createQuery("from ProblemClass"); 
    return query.list(); 
} 

Et juste pour le rendre complet, voici le code générique pour l'insérer (avant de récupérer dans un autre RUN l'application):

public void save(Persistent persistent) { 
    session.saveOrUpdate(persistent); 
} 

Répondre

21

Eureka, je l'ai trouvé!

Le problème était le suivant:

Les données du tableau ThirdClass n'a pas persisté correctement. Étant donné que ces données ont été référencé à partir MyDbObject via

optional = false 

Hibernate fait une jointure interne, ramenant ainsi un résultat vide pour la jointure. Parce que les données étaient là si elles étaient exécutées dans une session (dans le cache je suppose), cela n'a pas posé de problème. MySQL n'impose pas l'intégrité de la clé étrangère et ne se plaint donc pas lors de l'insertion de données corrompues.

Solution: facultatif = insertion correcte ou correcte des données.

+7

Utilisez les tables InnoDB ... –

+0

Merci beaucoup d'avoir posté la réponse! – Lisa

2

Sonne comme votre encartage de transaction est rollbacked

+0

Désolé de ne pas être clair: les données ont été insérées dans un autre RUN de l'application. Il est définitivement dans la base de données, comme je peux le voir via une requête SQL après la fin de l'application. Et après que je reçois l'erreur dans la première requête de la base de données. – roesslerj

5

raisons possibles:

  1. La ligne a été insérée par la première session, mais la transaction n'a pas été validée lorsque la deuxième session a tenté d'y accéder.
  2. La première session est restaurée en raison d'une raison quelconque.
+0

Désolé également de ne pas être clair: les données ont été insérées dans un autre RUN de l'application. Il est définitivement dans la base de données, comme je peux le voir via une requête SQL après la fin de l'application. Et après que je reçois l'erreur dans la première requête de la base de données. – roesslerj

0

S'il vous plaît mettre à jour votre fichier de configuration hibernate comme indiqué ci-dessous:

property start tag name="hbm2ddl.auto" create/update property close tag 
1

Cela pourrait être votre cas, de bien vouloir vérifier ma réponse sur un autre poste.

https://stackoverflow.com/a/40513787/6234057

J'ai eu la même exception Hibernate. Après le débogage pendant quelque temps, j'ai réalisé que le problème est causé par les enregistrements enfant orphelins.

Comme beaucoup se plaignent, quand ils recherchent l'enregistrement il existe. Ce que je me suis rendu compte est que le problème n'est pas dû à l'existence de l'enregistrement, mais hiberner ne pas le trouver dans la table, plutôt il est dû aux enregistrements orphelins d'enfant.

Les enregistrements qui ont référence aux parents inexistants!

Ce que j'ai fait, trouver les références de clé étrangère correspondant à la table liée au bean.

Pour trouver des références clés étrangères dans développeur SQL

1.Save le code XML ci-dessous dans un fichier (fk_reference.xml)

<items> 
<item type="editor" node="TableNode" vertical="true"> 
<title><![CDATA[FK References]]></title> 
<query> 
    <sql> 
     <![CDATA[select a.owner, 
         a.table_name, 
         a.constraint_name, 
         a.status 
       from all_constraints a 
       where a.constraint_type = 'R' 
         and exists(
          select 1 
          from all_constraints 
          where constraint_name=a.r_constraint_name 
            and constraint_type in ('P', 'U') 
            and table_name = :OBJECT_NAME 
            and owner = :OBJECT_OWNER) 
          order by table_name, constraint_name]]> 
    </sql> 
</query> 
</item> 

2.Ajoutez Définis par l'Utilisateur extension à SQL Developer

Pour trouver les enregistrements orphelins dans toutes les tables référencées

select * from CHILD_TABLE où foreignkey pas (sélectionnez primaryKey de table_parent) ;

Supprimez ces enregistrements orphelins, validez les modifications et redémarrez le serveur si nécessaire.

Cela a résolu mon exception. Vous pouvez essayer la même chose.

2

raison principale derrière cette question est non-concordance des données, par exemple, j'ai mapping class entité appelée « X » et il a la colonne « colonne1 » et a référence à la table colonne « colonne1 » « Y » comme ci-dessous

@OneToOne(cascade = CascadeType.ALL) 
@JoinColumn(name = "column1", referencedColumnName = "column1") 
public Y getColumn1() { 
    return Y; 
} 

Dans ce cas, si la table X colonne 1 a une valeur mais que la table Y colonne 1 n'a pas la valeur. Ici, le lien échouera.

C'est la raison pour laquelle nous allons obtenir Hibernate ObjectNotFound exception

Ce problème peut également être résolu en créant le modèle de données approprié comme la création d'une indexation appropriée et des contraintes (clé primaire/clé étrangère) ..

0

J'ai trouvé que dans Oracle ce problème peut également être causé par un problème d'autorisations. L'instance ProblemClass référencée par l'occurrence MyDbObject peut exister mais possède des autorisations qui ne permettent pas à l'utilisateur actuel de le voir, même si l'utilisateur peut voir le MyDbObject en cours.

Questions connexes