¿Cómo puedo mezclar Hibernate y Swing de una buena manera
-
28-09-2019 - |
Pregunta
Tengo algunas preguntas acerca de la interacción con Hibernate:
- ¿Uso o openSession getCurrentSession (sin JTA, hilo en su lugar)?
-
¿Cómo mezclo operaciones sesión con el Swing GUI? Es bueno tener algo como el siguiente código en una clase JavaBean?
public void actionPerformed(ActionEvent event) { // session code }
-
¿Puedo agregar a mis métodos entidades que contiene consultas HQL o se trata de una mala práctica? Por ejemplo:
// This method is in an entity MyOtherEntity.java class public int getDuration(){ Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); int sum = (Integer) session.createQuery("select sum(e.duration) as duration from MyEntity as e where e.myOtherEntity.id=:id group by e.name"). .setLong("id", getId()); .uniqueResult(); return sum; }
¿Cómo puedo hacer esto de una manera mejor y más elegante?
Actualizar Una práctica ampliamente utilizada es hacer una clase de servicio / DAO para lograr una operación CRUD de nuestra clase entidades. Pero ¿por qué es tan bueno? ¿Por qué tengo que escribir una clase para cada uno de mis entidades para su gestión? ¿Dónde está la verdadera ventaja?
ACTUALIZACIÓN 2 La clase de servicio es un patrón DAO? ¿Qué significa esto? Arthur Ronald FD de García es un patrón DAO, es esto lo que se llama una "capa de servicio"?
Solución
Si quieres confiar en la API de Hibernate llanura se puede utilizar una capa de Servicio, porque
- Se Caso de uso impulsada
- fronteras Delimitar transacción
Así se puede crear un AccountService, por ejemplo, como
public static path.to.HibernateUtil.getSessionFactory;
public class AccountService {
public void withdraw(Integer accountNumber, BigDecimal amount) throws Exception {
/**
* Here you set up Transaction boundaries
*/
getSessionFactory().getCurrentSession().beginTransaction();
// Some actions goes here
getSessionFactory().getCurrentSession().getTransaction().commit();
}
}
Por lo general, necesita un depósito al realizar alguna acción dentro de su capa de servicios. Se puede pensar en repositorio como un proveedor de datos y almacenamiento . Aquí se puede ver cómo puedo implementar mi repositorio.
Si quieres una mantenible y legible HQL consulta ??strong>, yo le asesoramiento externalizar sus consultas HQL en un archivo XML multline y exteriorizada
<?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">
<hibernate-mapping>
<query name="GIFT_CARDS_WITH_BUYER">
<![CDATA[
from
GiftCard c
left join fetch
c.buyer
where
c.recipientNotificationRequested = 1
]]>
</query>
<query name="GIFT_CARDS_WITHOUT_NO_RELATIONSHIP">
<![CDATA[
from
GiftCard
]]>
</query>
</hibernate-mapping>
Así que dentro de su swing de interfaz gráfica de usuario de eventos, puede llamar a su capa de servicios como
public void actionPerformed(ActionEvent event) {
// Some related Swing GUI actions goes here (retrieve User input, validate data and so on...)
accountService.withdraw(accountNumber, new BigDecimal(amount));
}
Y no es una idea buena persistencia Para utilizar las acciones dentro de su Entidad. Si es necesario realizar la persistencia temas relacionados dentro de su Entidad, yo creo que es mejor que pase su repositorio como parámetro a su Entidad
public class Account {
public void doSomething(AccountRepository repository) {
// code goes here
}
}
Tal vez usted quiere ver este Tema
Me consejos que eche un vistazo a Java Persistence con Hibernate libro, capítulo 9 (Trabajar con objetos). TCA : lea con atención
Actualizar
¿Por qué es bueno tener una capa de servicio?
En primer lugar
- Es Caso de uso conducido (Señala a lo que su aplicación debe hacer)
En segundo lugar
- Se delimitan los límites de transacción
Supongamos que aquí va la capa de servicio
public class MyService {
public void doSomething() {
getSessionFactory().beginTransaction();
// A POJO doing some operation
// Other POJO doing other operation
// Another POJO doing another operation
getSessionFactory().getTransaction().commit();
}
}
Aviso que acaba de definir un límite de transacción en lugar de definir cada uno dentro de cada POJO. Y más, ¿qué ocurre si su regla de negocio dentro de su necesidad Swing GUI para ser utilizado dentro de otro componente. Va a utilizar un Ctrl-c + Ctrl-v ???