Question

En supposant que les correspondances suivantes sont fournies:

<class name="A" table="a_table">
  <id name="id"/>
  <many-to-one name="entityB" column="fk_B" not-null="false" unique="true"/>
</class>

<class name="B" table="b_table">
  <id name="id"/>
</class>

classe Java:

public class A {
   private long id;
   private B entityB;
   // getters and setters skipped
}

Est-il possible de changer le mapping Hibernate pour que clé étrangère est toujours appliquée et créée par Mise en veille prolongée lors du démarrage , mais A classe ressemblerait comme suit:

public class A {
   private long id;
   private long idOfB;
   // getters and setters skipped
}

Je comprends que si je convertir en un <many-to-one... <property... cela fonctionnerait, mais la clé étrangère ne serait pas exécutée par la base de données.

Je dois faire cela parce que B objet peut (ou non) être initialisé séparément, ce qui cause parfois org.hibernate.LazyInitializationException: could not initialize proxy - no Session exceptions à se produire lorsque a.getB() est appelé. Je préférerais l'avoir comme long idOfB et charger un objet tout à chaque fois est nécessaire; ce serait également le chargement de l'objet A plus rapide.

Je crois que ma question est très similaire à celui-ci , mais la solution proposée (pour utiliser le chargement paresseux) ne convient pas dans mon cas, même si je l'appelle a.getB().getId(), je reçois LazyInitializationException alors si je l'appelle a.getIdOfB() je ne voudrais pas.

Merci beaucoup à l'avance.

Était-ce utile?

La solution

Comme dit

  

Je comprends que si je convertir mais la clé étrangère ne serait pas exécutée par la base de données .

Donc, mon conseil est: utiliser à la fois

public class EntityA {

    private Integer idOfB;

    private EntityB entityB;

    // getter's and setter's

}

<class name="A" table="a_table">
    <id name="id"/>
    <property name="idOfB" column="fk_B" not-null="false" unique="true"/>
    <many-to-one name="entityB" update="false" insert="false" column="fk_B"/>
</class>

Avis lorsque deux propriétés partagent la même colonne, vous devez mettre les paramètres à ce sujet dans une seule propriété . Dans le cas contraire, Hibernate va se plaindre des erreurs. Il explique pourquoi je définir la mise à jour = « false » et insérer = « false » dans la propriété entityB.

Cordialement,

Autres conseils

Vous pouvez toujours créer la clé étrangère manuellement DDL dans votre mise en veille prolongée fichier hbm.xml:

<hibernate-mapping>
    ...
    <database-object>
        <create>[CREATE FK]</create>
        <drop>[DROP FK]</drop>
    </database-object> 
</hibernate-mapping>

Vous pouvez également la portée de cette si différents dialectes doivent être pris en charge.

Consultez 5.7. objets base de données auxiliaire

Une autre approche que vous pourriez prendre est de définir le FK avec votre carte B plutôt que A la cartographie. J'ai ajouté le code JPA, vous auriez à traduire dans votre fichier de mappage de mise en veille prolongée si vous ne l'utilisez des annotations.

@Entity
public class B
{
    private long id;
    private List<A> aList;

    @Id
    @Column( name = "ID" )
    public long getId()
    {
        return id;
    }

    @OneToMany
    @JoinColumn( name = "B_ID" )
    public List<A> getAList()
    {
        return aList;
    }
    public void setId( long id )
    {
        this.id = id;
    }
    public void setAList( List<A> aList )
    {
        this.aList = aList;
    }        
}

A.java ne ressemblera à ceci:

@Entity
public class A
{
    private long id;
    private long idOfB;

    @Id
    @Column( name = "ID" )
    public long getId()
    {
        return id;
    }
    @Column( name = "B_ID" )
    public long getIdOfB()
    {
        return idOfB;
    }
    public void setId( long id )
    {
        this.id = id;
    }
    public void setIdOfB( long idOfB )
    {
        this.idOfB = idOfB;
    }   
}

Je vous recommande d'associer des objets à des objets pour obtenir tous les avantages de la mise en veille prolongée. Je pense que le problème est l'exception que vous obtenez. En effet, la session Hibernate est déjà fermé lorsque vous essayez d'obtenir l'objet paresseux. Il y a plusieurs postes dans ce blog qui montrent des réponses à ce problème, par exemple celui-ci: texte .

Dans le cas où vous utilisez printemps, vous pouvez utiliser OpenEntityManagerInViewFilter si la session garderez ouverte jusqu'à ce que la vue est renderes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top