Hibernate gestionnaire de transactions configurations au Printemps
Dans mon projet j'utilise Hibernate avec programmatiques la démarcation des transactions.
À chaque fois, dans mon Service méthodes-je écrire quelque chose de semblable.
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
.. perform operation here
session.getTransaction().commit();
Maintenant, je vais refactoriser mon code avec déclarative, la gestion des transactions. Ce que j'ai maintenant ...
<context:component-scan base-package="package.*"/>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="mySessionFactory"/>
</property>
</bean>
Classe de Service:
@Service
public class TransactionalService {
@Autowired
private SessionFactory factory;
@Transactional
public User performSimpleOperation() {
return (User)factory.getCurrentSession().load(User.class, 1L);
}
}
Et simple test -
@Test
public void useDeclarativeDem() {
FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("spring-config.xml");
TransactionalService b = (TransactionalService)ctx.getBean("transactionalService");
User op = b.performSimpleOperation();
op.getEmail();
Lorsque j'essaie d'obtenir l'email de l'utilisateur en dehors de la méthode, j'ai eu l'initialisation tardive exception, le courriel est mon cas, c'est une simple chaîne de caractères. Hibernate n'est pas à même d'effectuer des requêtes sql, jusqu'à ce que j'appelle toutes les getters sur mon POJO.
1) ce que je fais de mal ici ?
2) cette approche Est-elle valide ?
3) Pouvez-vous suggérer les opensources projet qui travaillent sur spring/hibernate annotations en fonction de la configuration ?
Mise à jour
Pour quelque raison que si je remplace getCurrentSession avec openSession ce code fonctionne très bien. Quelqu'un peut m'expliquer s'il vous plaît ?
Merci
simple chaîne de caractères dans le même tableau
OriginalL'auteur user12384512 | 2011-02-27
Vous devez vous connecter pour publier un commentaire.
Ok, j'ai enfin compris quel était le problème. Dans le code ci-dessus, j'ai utilisé de la charge au lieu de les obtenir. Session.la charge n'a pas atteint réellement la base de données. C'est la raison pour laquelle je deviens paresseux-initialisation de l'exception à l'extérieur de @Transactional méthode
Si j'utilise openSession au lieu de getCurrentSession, la séance est ouverte à l'extérieur de la portée de printemps conteneur. Comme résultat de la session n'était pas près et que ça me permet de lire les propriétés de l'objet à l'extérieur de @Transactional méthode
OriginalL'auteur user12384512
La raison Hibernate ne pas effectuer les requêtes SQL jusqu'à ce que vous appelez les getters est parce que je crois que le FetchType est définie de PARESSEUX. Pour résoudre ce problème, vous devez modifier le FetchType à la HÂTE dans votre POJO:
J'ai personnellement jamais eu de spécifier des types de Base d'avoir une AVIDE FetchType donc je ne suis pas entièrement sûr de savoir pourquoi votre configuration nécessite la ce. Si c'est uniquement dans vos tests, il pourrait être dû à la façon dont vous avez votre JUnit tests configuré. Il doit avoir quelque chose comme ceci sur la déclaration de la classe:
Que pour une bonne ressource je trouve toujours SpringByExample pour être utile.
MODIFIER
Donc je ne suis pas entièrement sûr de ce qui est erroné avec votre configuration. Il ne différer de la façon dont le mien jusqu'alors voici ma configuration typique dans l'espoir que cela aide. Le
hibernate.transaction.factory_class
pourrait être une propriété de clé vous sont manquants. J'utilise aussi leAnnotationSessionFactoryBean
:Pourriez-vous s'il vous plaît poster la trace de la Pile de votre LazyInitializationException? Il semble étrange qu'il n'y aurait pas une certaine forme d'initialisation différée si c'est l'exception.
ERREUR org.mise en veille prolongée.LazyInitializationException - n'a pas pu initialiser proxy - pas de Session org.mise en veille prolongée.LazyInitializationException: impossible d'initialiser le proxy - pas de Session au org.mise en veille prolongée.proxy.AbstractLazyInitializer.initialiser(AbstractLazyInitializer.java:132) at org.mise en veille prolongée.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:174) à org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
OriginalL'auteur Ian Dallas
De mise en veille prolongée de la documentation https://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html/ch11.html#objectstate-loading:
Être conscient que load() lève une exception irrécupérable s'il n'existe pas de base de données correspondant à la ligne. Si la classe est mappé avec un proxy, load() retourne juste un non initialisée proxy et ne fait pas de frapper la base de données jusqu'à ce que vous appeler une méthode de la procuration. Ceci est utile si vous souhaitez créer une association à un objet sans le charger à partir de la base de données. Il permet également de multiples instances d'être chargé comme un lot si batch-size est défini pour le mapping de la classe.
De documentation ci-dessus dans votre cas, la fève est mappé avec le printemps proxy afin de ne charger que les retours. Par conséquent, vous devez utiliser get() au lieu de charger() qui atteint toujours la base de données.
OriginalL'auteur chammu