2009-10-18 11 views
5

nuevo en primavera y aquí @stackoverflowprimavera @Transactional fusionar y persistir pregunta

Estoy construyendo un inventario autónomo & Ventas seguimiento de aplicaciones (Apache Pivot/primavera/JPA/Hibernate/MySQL) para que una empresa distribuidora .

Hasta ahora creo que todo es CRUD, así que planeo tener una clase base con todo @Transactional.

Luego tengo un problema con mi método genérico de guardado. ¿Persistir y combinar el método de EntityManager de Spring tiene una diferencia?

Intenté ejecutar y llamé al guardar tanto para insertar como para actualizar y funcionó bien (creo que spring actualiza automáticamente la entidad cada vez que llamo a mi método save // ​​vi las consultas de hibernación registradas, ¿verdad?).

@Transactional 
public abstract class GenericDAO { 

    protected EntityManager em; 

// em [email protected]/setter 

    public void save(T t) { 
//  if (t.getId() == null) // create new 
//  { 
//   em.persist(t); 
//  } else // update 
//  { 
      em.merge(t); 
//  } 
    } 
} 

Y por cierto, que tiene una configuración como esta, no voy a ser mucho comprometer el rendimiento correcto? Como llamar a salesDAO.findAll() para generar informes (que no necesita ser transaccional, ¿verdad?).

gracias !!!

Respuesta

5

This SO question es una buena discusión de persistir frente a fusión, y la respuesta aceptada lo explica bastante bien. La otra respuesta también vincula a una buena publicación de blog sobre esto.

De acuerdo con la primera respuesta en this other post, parece que sería posible llamar a merge para guardar y actualizar una entidad, pero no es así como lo hice. En mis aplicaciones Spring/JPA, solo hago que mis DAO amplíen JpaDaoSupport y utilicen getJpaTemplate() de la siguiente manera.

/** 
* Save a new Album. 
*/ 
public Album save(Album album) { 
    getJpaTemplate().persist(album); 
    return album; 
} 

/** 
* Update an existing Album. 
*/ 
public Album update(Album album) { 
    return getJpaTemplate().merge(album); 
} 
+0

Invito esta es la forma más sencilla de hacerlo. Entonces, si tengo JpaDaoSupport y obtengo una entidad de él, ¿se realizarán automáticamente los cambios? Creo que tendré dos variantes de método guardar, una que persiste y otra que llama "flush". ¿Algún comentario sobre esto? – thirdy

+0

¿Quiere decir automático como cometido sin guardar ni actualizar? Si es así, no lo creo, siempre llamo guardar en una nueva entidad o actualizar en una existente para persistir. Nunca tuve que llamar al método de descarga, pero el acceso a mi base de datos es bastante simple para cualquier solicitud dada. –

+0

Tendré que dejar de intentar la primavera por ahora. Solo curiosidad, ¿cómo mejora Grails en esto? No tendré que enfrentarme a problemas como estos en Grails ¿no? – thirdy

4

El link a la otra pregunta para Kaleb publicada hace un buen trabajo de cubrir las diferencias y aspectos críticos de persistir() vs merge(). Sin embargo, siempre he implementado mis clases Dao con un método save() que solo llama a merge() para manejar las inserciones y las actualizaciones, y nunca me he encontrado con ninguno de los errores persistidos() frente a merge().

En cuanto a rendimiento y métodos transaccionales: Usando @Transactional en métodos que sólo son operaciones de lectura realmente no tendrá impacto en el rendimiento, aunque yo prefiero usar las anotaciones de nivel de método para que yo pueda saber fácilmente qué métodos son actualizaciones y que son lecturas. Puede hacer esto configurando el atributo readOnly en la anotación @Transactional.

Si usted sigue una convención de nomenclatura en sus métodos (es decir, cualquier método de lectura siempre comienza con getXXX), también se puede utilizar la sintaxis poincut en su archivo de configuración de primavera para hacer automáticamente esta diferenciación:

<tx:advice id="txAdvice" transaction-manager="txManager"> 
    <tx:attributes> 
     <tx:method name="get*" read-only="true"/> 
     <tx:method name="*"/> 
    </tx:attributes> 
    </tx:advice> 

Véase el Spring documentation on Transactions para más información.

Además, normalmente pongo los atributos @Transactional un nivel por encima de mis clases Dao, en una capa de servicio. Los métodos en las clases de Dao son entonces operaciones de base de datos distintas para cada llamada de método, mientras que los métodos de servicio pueden realizar una única confirmación/retrotracción para una serie de actualizaciones.

+0

gracias por responder. Creo que me apegaré a JPA puro, (no tengo mucha necesidad de flexibilidad) – thirdy

Cuestiones relacionadas