Pregunta

se proporcionan

Suponiendo las siguientes asignaciones:

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

clase Java:

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

¿Es posible cambiar el mapeo de Hibernate para que clave externa todavía se aplica y creado por Hibernate en el inicio , pero A clase se vería como el siguiente:

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

Yo entiendo que si me convierto en un <many-to-one... <property... esto funcionaría, pero la clave externa no se aplicarían por la base de datos.

Necesito hacer esto porque podría objetar B (o no) ser inicializado por separado que a veces causas excepciones a org.hibernate.LazyInitializationException: could not initialize proxy - no Session se producen cuando a.getB() se llama. Yo preferiría tenerlo como long idOfB y cargar objeto entero siempre que sea necesario; Esto también haría que la carga de A objeto más rápido.

Creo que mi pregunta es muy similar a éste, sin embargo, la solución que se ofrece (para usar la carga diferida) no es apropiado en mi caso, ya que incluso si llamo a.getB().getId(), me gustaría obtener LazyInitializationException mientras que si llamo a.getIdOfB() que no lo haría.

Muchas gracias de antemano.

¿Fue útil?

Solución

Como dijo

  

Yo entiendo que si convierto , pero la clave externa no se aplicarían por la base de datos.

Así que mi consejo es: utilizar tanto

public class EntityA {

    private Integer idOfB;

    private EntityB entityB;

    // getter's and setter's

}

y

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

Aviso cuando dos propiedades comparten la misma columna, usted tiene que poner los ajustes de ello en una sola propiedad . De lo contrario, Hibernate se quejan algunos errores. Esto explica por qué yo defino update = "false" e inserte = "false" en la propiedad entityB.

cordiales,

Otros consejos

Siempre se puede crear la clave externa DDL manualmente en su archivo hbm.xml de hibernación:

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

También puede alcance este caso diferentes dialectos tienen que ser apoyada.

5,7. base de datos auxiliar objetos

Otro enfoque que podría tomar es definir el FK con su asignación B en vez de la asignación A. He añadido el código de la APP, que tendría que traducir esto a su archivo de asignación de hibernación si no está utilizando anotaciones.

@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 no se vería así:

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

Te recomiendo a los objetos asociados a objetos para conseguir ventajas completas de hibernación. Creo que el problema es la excepción que se obtiene. Esto se debe a sesión de Hibernate ya está cerrado cuando intenta obtener el objeto perezoso. Hay varios puestos en este blog que muestran respuestas a este problema, por ejemplo ésta: texto.

En caso de que esté usando primavera se puede utilizar OpenEntityManagerInViewFilter así, mantendrá abierta la sesión hasta que la vista es renderes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top