la session hibernate.rincer avec le printemps @transactional
Je suis à l'aide de spring et hibernate dans mon application et à l'aide de printemps de la transaction.
Donc, j'ai de la couche de service avec l'annotation @transaction sur les méthodes et les DAO couche ayant des méthodes de requête de base de données.
@Transactional(readOnly = false)
public void get(){
}
Le problème est lorsque je veux enregistrer un objet dans la base de données,puis-je utiliser session.flush()
à la fin de DAO méthode de la couche.Pourquoi?
Je pense que si j'ai annoté @transaction,le printemps devrait automatique de valider la transaction à la fin de la méthode de service.
DAO couche :
public BaseEntity saveEntity(BaseEntity entity) throws Exception {
try {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(entity);
session.flush();
} catch (HibernateException he) {
throw new Exception("Failed to save entity " + entity);
}
return entity;
}
De la couche de Service :
@Transactional(readOnly = false)
public BaseEntity saveEntity(BaseEntity entity) throws Exception {
return dao.saveEntity(entity);
}
printemps config :
<context:property-placeholder properties-ref="deployProperties" />
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Activate Spring Data JPA repository support -->
<jpa:repositories base-package="com" />
<!-- Declare a datasource that has pooling capabilities-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="${app.jdbc.driverClassName}"
p:jdbcUrl="${app.jdbc.url}"
p:user="${app.jdbc.username}"
p:password="${app.jdbc.password}"
p:acquireIncrement="5"
p:idleConnectionTestPeriod="60"
p:maxPoolSize="100"
p:maxStatements="50"
p:minPoolSize="10" />
<!-- Declare a JPA entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceXmlLocation="classpath*:META-INF/persistence.xml"
p:persistenceUnitName="hibernatePersistenceUnit"
p:dataSource-ref="dataSource"
p:jpaVendorAdapter-ref="hibernateVendor"/>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource" p:configLocation="${hibernate.config}"
p:packagesToScan="com" />
<!-- Specify our ORM vendor -->
<bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:showSql="false"/>
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>
- le printemps est-il pour vous, et
readonly=false
est par défaut, vous n'avez pas le déclarer - Je pense validation automatique n'a pas l'intention de vider
Session
DB immédiatement, mais en faisant les modifications faites dans cette transaction disponibles à d'autres opérations de travailler avec le mêmeSession
. - Si vous avez correctement configuré les transactions alors oui... Mais votre configuration est erronée. Pourquoi êtes-vous en utilisant à la fois un
SessionFactory
etEntitymanagerFactory
? Vous n'utilisez qu'un seul gestionnaire de transactions. La question principale est de votre installation. - Ouais, d'accord avec @M. Deinum, vous êtes à l'aide d'une SessionFactory qui n'est pas liée au Printemps TransactionManager. Donc, le printemps est de ne pas prendre soin de vos transactions dans votre installation.
Vous devez vous connecter pour publier un commentaire.
Oui, si vous avez
@Transactional
pour votre DAO méthode, puis vous avez besoin de ne pas rincer la session manuellement, hibernate va prendre soin de rinçage de la session dans le cadre de la validation de la transaction, si l'exploitation de la méthode sont couronnées de succès.Vérifier ce lien pour savoir comment @Transactional œuvres - Printemps - @Transactional - Ce qui se passe en arrière-plan?
sessionFactory
dans votre DAO couche est injecté par Ressort seulement?Par défaut, hibernate piles ses requêtes de sorte qu'ils peuvent être optimisés lorsqu'ils sont finalement exécutés sur la base de données.
Le trou de point de rincer rincer de cette pile et de l'exécuter dans votre transaction sur la base de données. Votre en laissant le "sauver" de la maison de la jvm et exécuter votre requête sur un gros étrange de la base de données.
C'est pourquoi vous ne pouvez pas sélectionner quelque chose que vous avez juste sauvé sans rincer. Il est tout simplement pas encore dans la base.
Le sens de s'engager à la fin d'une fois la transaction et de faire des modifications de la base de données visibles pour les autres. Une fois le commit a été exécuté il n'y a pas de retour possible.
Franchement, je ne suis pas sûr si c'est une meilleure pratique, mais normale pour les opérations CRUD, vous devriez être en mesure d'ajouter de la chasse dans votre couche dao.
De cette façon, vous n'avez pas besoin de s'inquiéter à ce sujet dans la couche de service.
Si vous voulez java pour optimiser votre transaction puis vous devrez l'ajouter dans votre couche de service. Mais n'oubliez pas que vous n'avez pas besoin de résoudre les problèmes de performances quand il n'y en a pas! Bouffées de chaleur partout dans votre code dans la couche de service n'est pas bon pour la lisibilité du code. Keep it simple et stupide 😉