Domanda

Supponendo i seguenti mappature sono forniti:

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

E 'possibile cambiare la mappatura Hibernate in modo che chiave esterna è ancora applicata e creato da Hibernate all'avvio , ma di classe A sarà simile come il seguente:

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

Capisco che se converto <many-to-one... in un <property... questo avrebbe funzionato, ma chiave esterna non sarebbe stato imposto dal database.

Ho bisogno di fare questo perché oggetto B potrebbe (o non potrebbe) essere inizializzato separatamente che a volte le cause org.hibernate.LazyInitializationException: could not initialize proxy - no Session a verificarsi quando si chiama a.getB() eccezioni. Preferirei avere come un long idOfB e caricare intero oggetto quando è necessario; questo sarebbe anche fare carico di oggetti A più veloce.

Credo che la mia domanda è molto simile a questo , eppure la soluzione offerta (per usare lazy loading) non è appropriato nel mio caso, come anche se chiamo a.getB().getId(), avrei avuto LazyInitializationException mentre se chiamo a.getIdOfB() non lo farei.

Grazie mille in anticipo.

È stato utile?

Soluzione

Come detto

  

Capisco che se converto ma chiave esterna non verrebbe applicato dal database.

Quindi il mio consiglio è: utilizzare entrambi

public class EntityA {

    private Integer idOfB;

    private EntityB entityB;

    // getter's and setter's

}

E

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

Avviso quando due proprietà condividono la stessa colonna, devi mettere le impostazioni su di esso in una sola proprietà . In caso contrario, Hibernate si lamenterà alcuni errori. Ciò spiega perché i definisco aggiornamento = "false" e inserire = "false" in proprietà entityB.

saluti,

Altri suggerimenti

Si può sempre creare manualmente la chiave esterna DDL nel file hbm.xml hibernate:

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

È anche possibile campo di applicazione questo se diversi dialetti devono essere supportati.

5.7. oggetti di database ausiliario

Un altro approccio si può prendere è quello di definire l'FK con la mappatura B piuttosto che la A mappatura. Ho aggiunto il codice di APP, che avrebbe dovuto tradurre questo al vostro file di mapping Hibernate, se non si sta usando le annotazioni.

@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 non sarebbe simile a questa:

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

Vi consiglio di associare oggetti a oggetti per ottenere vantaggi completi di Hibernate. Credo che il problema è l'eccezione che si ottiene. Questo perché la sessione Hibernate è già chiusa quando si tenta di ottenere l'oggetto pigro. Ci sono diversi messaggi in questo blog che mostrano le risposte a questo problema, per esempio questa: testo .

Nel caso in cui si sta utilizzando la primavera è possibile utilizzare OpenEntityManagerInViewFilter così la sessione continuano fino a che la vista è renderes.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top