2009-02-02 12 views
5

Tengo dos tablas relacionadas entre sí utilizando una relación de uno a varios: empleado -> departamento: y relación a través de department_id en la tabla de empleados.Modo de búsqueda de cambio de hibernación en tiempo de ejecución

uso de hibernación: y mis archivos de asignación de hibernación son:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools 
--> 
<hibernate-mapping default-lazy="false"> 
<class catalog="moi" 
    name="com.ebla.moi.correspondence.model.entity.user.User" table="user"> 
    <id name="id" type="java.lang.Long"> 
    <column name="id"/> 
    <generator class="identity"/> 
    </id> 
    <many-to-one 
    class="com.ebla.moi.correspondence.model.entity.department.Department" 
    fetch="select" name="department"> 
    <column name="department_id"/> 
    </many-to-one> 
    <property generated="never" lazy="false" name="name" type="java.lang.String"> 
    <column length="128" name="name" not-null="true"/> 
    </property> 
    <property generated="never" lazy="false" name="email" type="java.lang.String"> 
    <column length="128" name="email" not-null="true" unique="true"/> 
    </property> 
    <property generated="never" lazy="false" name="maritalStatus" type="java.lang.Short"> 
    <column name="marital_status" not-null="true"/> 
    </property> 
    <property generated="never" lazy="false" name="hireDate" type="java.lang.String"> 
    <column length="64" name="hire_date"/> 
    </property> 
</class> 
</hibernate-mapping> 

y el segundo archivo de asignación es:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools 
--> 
<hibernate-mapping default-lazy="false"> 
<class catalog="moi" 
    name="com.ebla.moi.correspondence.model.entity.department.Department" table="department"> 
    <id name="id" type="java.lang.Long"> 
    <column name="id"/> 
    <generator class="identity"/> 
    </id> 
    <property generated="never" lazy="false" name="name" type="java.lang.String"> 
    <column length="256" name="name" unique="true"/> 
    </property> 
    <set inverse="true" name="users" sort="unsorted"> 
    <key> 
    <column name="department_id"/> 
    </key> 
    <one-to-many class="com.ebla.moi.correspondence.model.entity.user.User"/> 
    </set> 
</class> 
</hibernate-mapping> 

Mi problema es: a veces tengo que conseguir que el empleado con su departamento , y otras veces solo necesito la información del empleado sin información del departamento ... y lo mismo con el departamento con el empleado ... usando el archivo de mapeo arriba del hibernate traigo el departamento y sus usuarios si necesito el empleado o no ... cómo definir mis necesidades para hibernar a f Etch justo lo que necesito ...

gracias

Respuesta

10

Se podría trazar la relación como "perezosa" y escribir dos consultas para obtener sus datos:

  • La simple consulta habitual para obtener su datos ("perezoso"). P.ej. "seleccione e de Employee e where ..."

  • La misma consulta que usa "fetch join" para forzar a Hibernate a buscar "childs". P.ej. "Selecto e a partir del Empleado dejó join fetch e.department donde ..."

LLP, Andrea

8

Puede utilizar ICriteria a buscar a su empleado.

Usted puede utilizar el método SetFetchMode del ICriteria para determinar si el Departamento debe ser traída, o no:

Esto se asegurará de que el Departamento no es exagerado:

ICriteria crit = theSession.CreateCriteria (typeof(Employee)); 
crit.SetFetchMode ("Department", FetchMode.Lazy) 

Con este código , se buscará el departamento.

ICriteria crit = theSession.CreateCriteria (typeof(Employee)); 
crit.SetFetchMode ("Department", FetchMode.Join) 

Algunos dicen que es la mejor práctica para usar el fetchMode defecto en las asignaciones (que sería perezoso, supongo), y especifique el fetchMode en cada escenario específico. (Es decir, en sus repositorios).

+0

No funciona para mí. Todavía obtiene las entidades asociadas, pero no usa una cláusula join. En cambio, llama a otra instrucción select. – supertonsky

2

Una forma de hacer esto es tener dos clases que representan un empleado:

  • Employee que tiene información asignada a través del departamento;
  • EmployeeSummary que solo tiene los datos del empleado en sí.

Ambas clases luego tener fijaciones independientes sobre la mesa employee, pero sólo Employee también tiene la relación en department definido.

Luego, cuando necesita toda la información, carga Employee instancias, y cuando solo necesita información del empleado, carga EmployeeSummary instancias.

Puede eliminar cualquier duplicación de enlaces ORM y lógica de negocios al introducir una superclase común como AbstractEmployee en ambas clases de empleados.

+1

No creo que sea una buena idea en esta situación. ¿Qué pasa si tus clases contienen BL complejo? Tendrás que duplicarlo? –

+0

No necesariamente si introduce la superclase común, pero es un buen punto: he actualizado la respuesta para reflejar esto. –

+0

¿Qué ocurre si en una sola sesión, tanto un empleado como un resumen de empleado, se cargan desde el mismo registro de la base de datos, se modifican uno o ambos? –

Cuestiones relacionadas