Stworzyłem aplikację z spring + hibernate, ale zawsze otrzymuję ten błąd. To moja pierwsza aplikacja z hibernacją, przeczytałem kilka poradników, ale nie mogę rozwiązać tego problemu. Gdzie ja robię źle?
To jest kod mojej aplikacji
ott 05, 2014 4:03:06 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
Informazioni: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1eab16b: startup date [Sun Oct 05 16:03:06 CEST 2014]; root of context hierarchy
ott 05, 2014 4:03:06 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
Informazioni: Loading XML bean definitions from class path resource [springConfig.xml]
ott 05, 2014 4:03:08 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
ott 05, 2014 4:03:08 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.6.Final}
ott 05, 2014 4:03:08 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
ott 05, 2014 4:03:08 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
ott 05, 2014 4:03:09 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
ott 05, 2014 4:03:09 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
ott 05, 2014 4:03:09 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Exception in thread "main" org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at coreservlets.StudentDAOImpl.create(StudentDAOImpl.java:19)
at coreservlets.MainApp.main(MainApp.java:14)
student.java
package coreservlets;
public class Student {
private Integer id;
private String name;
private Integer age;
public Integer getId(){return id;}//getId
public void setId(Integer id){this.id=id;}//setId
public String getName(){return name;}//getName
public void setName(String name){this.name=name;}//setName
public Integer getAge(){return age;}//getAge
public void setAge(Integer age){this.age=age;}//setAge
}//Student
studentDAO.java
package coreservlets;
import org.hibernate.SessionFactory;
public interface StudentDAO {
public void setSessionFactory(SessionFactory sessionFactory);
public void create(String name,Integer age);
}//StudentDAO
StudentDAOImpl.java
package coreservlets;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class StudentDAOImpl implements StudentDAO {
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory=sessionFactory;
}//setSessionFactory
public void create(String name,Integer age){
Session session=sessionFactory.getCurrentSession();
Student student=new Student();
student.setName(name);
student.setAge(age);
session.save(student);
}//create
}//StudentDAOImpl
MainApp.java
package coreservlets;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("springConfig.xml");
StudentDAOImpl student=(StudentDAOImpl) context.getBean("studentDAOImpl");
student.create("Alessandro", new Integer(33));
}//main
}//MainApp
springConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<context:annotation-config/>
<context:component-scan base-package="coreservlets"/>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_hibernate"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
<property name="initialSize" value="5"/>
<property name="maxTotal" value="10"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
</value>
</property>
</bean>
</beans>
sql
create table student
(
id integer not null auto_increment,
name varchar(20) not null,
age integer not null,
primary key(id)
);
sessionFactory.openSession()
transakcja zostanie wyłączona. Ponieważ to nie ta sama sesja. > Dodaj adnotację @Transactional of spring w serwisie klasy @Patrikoko jest poprawne! zobacz to pytanie: stackoverflow.com/questions/15620355/ ... przykład:@Transactional(readOnly = true, propagation = Propagation.REQUIRED, rollbackFor = {java.lang.Exception.class})
Odpowiedzi:
Musisz włączyć obsługę transakcji (
<tx:annotation-driven>
lub@EnableTransactionManagement
) i zadeklarowaćtransactionManager
i powinno działać poprzezSessionFactory
.Musisz dodać
@Transactional
do swojego@Repository
With
@Transactional
in your@Repository
Spring jest w stanie zastosować wsparcie transakcyjne do Twojego repozytorium.Twoja
Student
klasa nie ma adnotacji @ javax.persistence. *, Jak zakładam@Entity
, że konfiguracja mapowania dla tej klasy została zdefiniowana za pomocą XML.źródło
Miałem ten sam problem, ale w klasie, która nie była częścią warstwy usług. W moim przypadku menadżer transakcji został po prostu pozyskany z kontekstu
getBean()
metodą, a klasa należała do warstwy widoku - mój projekt wykorzystujeOpenSessionInView
technikę.sessionFactory.getCurrentSession()
Metoda została powodując ten sam wyjątek jako autora. Rozwiązanie dla mnie było raczej proste.Jeśli
getCurrentSession()
metoda zawiedzie,openSession()
powinno załatwić sprawę.źródło
sessionFactory.getCurrentSession();
powiedzie, sesja nie powinna zostać zamknięta, ale jeśli sięsessionFactory.openSession();
powiedzie, musi zostać zamkniętaFunction<Session,T>
oznaczającą „gdybym miał sesję, użyłbym jej do zrobienia X”. Następnie metoda obsługuje obsługę administracyjną i (jeśli to konieczne) wyrejestrowywanie sesji, a po prostu zwraca T. Więc zewnętrzni konsumenci usługi nigdy nie dostają sesjiDodaj adnotację @Transactional of spring w usłudze klasowej
źródło
W pliku xyz.DAOImpl.java
Wykonaj następujące kroki:
źródło
Dodałem tę konfigurację w web.xml i działa dobrze!
Dodatkowo, najbardziej sklasyfikowana odpowiedź daje mi wskazówki, jak zapobiec panice aplikacji przy pierwszym uruchomieniu.
źródło
Musisz zezwolić na transakcje za pomocą metody DAO. Dodaj,
nad metodami dao. I
@Transactional
powinien być z paczki:źródło
Miałem też ten błąd, ponieważ w pliku, w którym użyłem
@Transactional
adnotacji, importowałem niewłaściwą klasęZamiast javax użyj
źródło
Moim rozwiązaniem było (używając Springa) umieszczenie metody, która zawodzi, wewnątrz innej metody, która tworzy i zatwierdza transakcję.
Aby to zrobić, najpierw wstrzyknąłem:
I w końcu to zrobił:
źródło
@Transactional =javax.transaction.Transactional
. Połóż to tuż obok@Repository
.źródło
Moja konfiguracja była taka. Miałem QuartzJob , Service Bean i Dao. jak zwykle został skonfigurowany z LocalSessionFactoryBean (dla hibernacji) i SchedulerFactoryBean dla frameworka Quartz. podczas pisania zadania Quartz przez pomyłkę oznaczyłem go adnotacją @ Service , nie powinienem był tego robić, ponieważ używałem innej strategii do okablowania QuartzBean przy użyciu AutowiringSpringBeanJobFactory rozszerzającego SpringBeanJobFactory .
Więc to, co faktycznie się działo, to to, że dzięki Quartz Autowire, TX był wstrzykiwany do Job Bean i jednocześnie Tx Context został ustawiony na mocy adnotacji @ Service, a zatem TX tracił synchronizację !!
Mam nadzieję, że pomoże to tym, dla których powyższe rozwiązania naprawdę nie rozwiązały problemu. Używałem Springa 4.2.5 i Hibernate 4.0.1,
Widzę, że w tym wątku jest niepotrzebna sugestia, aby dodać adnotację @ Transactional do DAO (@ Repository ), czyli bezużyteczną sugestię, ponieważ @ Repozytorium ma wszystko, czego potrzebuje, nie musi specjalnie ustawiać tego @ transakcyjnego na DAO, ponieważ DAO są wywoływane z usług, które zostały już wstrzyknięte przez @Trasancational . Mam nadzieję, że mogą to być pomocne osoby, które razem używają Quartz, Spring i Hibernate.
źródło
Dodaj
transaction-manager
do swojej<annotation-driven/>
w wiosenno-servlet.xml:źródło
Sprawdź swoją klasę dao. Musi wyglądać tak:
I adnotacje:
źródło
Napotkałem ten sam problem i w końcu odkryłem, że element
<tx:annotaion-driven />
nie został zdefiniowany w klasie z adnotacjami,[dispatcher]-servlet.xml
gdzie element skanowania komponentu@service
włączał.Po prostu
<tx:annotaion-driven />
razem z elementem skanowania komponentowego problem zniknął.źródło
Mój podobny problem został rozwiązany za pomocą poniższych 2 podejść.
1) Poprzez ręczną obsługę transakcji:
2) Powiedz Springowi, aby otwierał i zarządzał transakcjami w Twoich
web.xml
filtrach i upewnij się, że używasz@Repository
@Transactional
:źródło
Dzięki za komentarz Mannedear. Używam springmvc iw moim przypadku muszę używać jako
dodam też kontekst wiosny do pom.xml i to działa
źródło
Miałem ten sam problem. Rozwiązałem to, wykonując następujące czynności:
Dodaj ten wiersz do
dispatcher-servlet
pliku:Sprawdź powyższą
<beans>
sekcję w tym samym pliku. Te dwie linie muszą być obecne:Upewnij się również, że dodałeś
@Repository
i@Transactional
gdzie używaszsessionFactory
.źródło
W tej klasie powyżej
@Repository
właśnie umieściłem jeszcze jedną adnotację@Transactional
, która zadziała. Jeśli to działa, odpowiedz (Y
/N
):źródło