2015-11-18 15 views
5

Không EntityManager với giao dịch thực tế có sẵn cho thread hiện hành - có thể không đáng tin cậy quá trình 'kéo dài' gọiKhông EntityManager với giao dịch thực tế có sẵn cho thread hiện hành - có thể không đáng tin cậy quá trình 'kéo dài' gọi

khi tôi làm một thử nghiệm với JUnit, kiên trì phương pháp làm việc và tôi thấy rằng đối tượng của tôi được đưa vào, nhưng khi tôi gọi phương thức thông qua điều khiển của tôi không hoạt động

đây là dự án của tôi:

applicationContext.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:tx="http://www.springframework.org/schema/tx" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:task="http://www.springframework.org/schema/task" 
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd 
     http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd 
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> 



<!-- <bean id="notification" class="com.app.sqli.notification.NotificationTask" /> --> 

<!-- <task:scheduled-tasks> --> 
<!--  <task:scheduled ref="notification" method="notifier" cron="*/2 * * * * *"/> --> 
<!-- </task:scheduled-tasks> --> 

<context:component-scan base-package="com.app.sqli" /> 

    <mvc:annotation-driven /> 
    <bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="packagesToScan" value="com.app.sqli.entities" /> 
     <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
     </property> 
     <property name="jpaProperties"> 
     <props> 
      <prop key="hibernate.hbm2ddl.auto">validate</prop> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> 
     </props> 
     </property> 
    </bean> 


    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
     <property name="url" value="jdbc:mysql://localhost:3306/sqli" /> 
     <property name="username" value="root" /> 
     <property name="password" value="" /> 
    </bean> 


    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactoryBean" /> 
    </bean> 


    <tx:annotation-driven /> 


</beans> 

mẫu của tôi Class:

package com.app.sqli.models; 

import javax.persistence.Entity; 
import javax.persistence.Id; 

@Entity 
public class Collaborateur { 

    @Id 
    private int id; 
    private String nom; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getNom() { 
     return nom; 
    } 

    public void setNom(String nom) { 
     this.nom = nom; 
    } 

} 

DAO tôi Lớp

package com.app.sqli.dao; 

import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 

import org.springframework.stereotype.Repository; 

import com.app.sqli.models.Collaborateur; 

@Repository 
public class CollaborateurDao implements IcollaborateurDao{ 

    @PersistenceContext 
    private EntityManager em; 

    @Override 
    public void addCollaborateur(Collaborateur c) { 
    em.persist(c); 

    } 

} 

Dịch vụ My Lớp

package com.app.sqli.services; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 

import com.app.sqli.dao.IcollaborateurDao; 
import com.app.sqli.models.Collaborateur; 

@Service 
@Transactional 
public class CollaborateurService implements IcollaborateurService{ 

    @Autowired 
    private IcollaborateurDao cdao; 

    @Override 
    public void addCollaborateur(Collaborateur c) { 
     cdao.addCollaborateur(c); 

    } 


} 

Và điều khiển của tôi

package com.app.sqli.controller; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.RequestMapping; 

import com.app.sqli.models.Collaborateur; 
import com.app.sqli.services.IcollaborateurService; 

@org.springframework.stereotype.Controller 
public class Controller { 
    @Autowired 
    private IcollaborateurService cserv; 

    @RequestMapping(value = "/index") 
    public String index(Model m) { 
     System.out.println("insertion ..."); 
     Collaborateur c = new Collaborateur(); 
     c.setId(11); 
     c.setNom("nom"); 
     cserv.addCollaborateur(c); 
     return "index"; 
    } 

} 
+1

ngoại trừ bạn đang nhận được là gì? Nếu không biết ngoại lệ, điều duy nhất tôi có thể nghĩ đến là sử dụng PersistenceContextType.Extended trên EM của bạn. @PersistenceContext (type = PersistenceContextType.EXTENDED) \t EntityManager em; – Mechkov

+0

Lỗi mà tôi đang gặp phải: org.springframework.web.util.NestedServletException: Yêu cầu xử lý không thành công; ngoại lệ lồng nhau là javax.persistence.TransactionRequiredException: Không có EntityManager với giao dịch thực sự có sẵn cho luồng hiện tại - không thể xử lý một cách tin cậy cuộc gọi 'persist' ' –

+1

Bạn đã thử dùng PersistanceContextType.Extended chưa? Tóm lại, điều này thay đổi từ EM giao dịch phạm vi thành một phiên đậu trạng thái ... – Mechkov

Trả lời

5

cảm ơn bạn @mechkov vì đã dành thời gian và trợ giúp của bạn, Sự cố của tôi được giải quyết bằng cách thay đổi tệp cấu hình của tôi, vì vậy tôi đã sử dụng Lớp cấu hình có chú thích và hoạt động của nó rất tốt, tôi vẫn không biết vấn đề ở đâu là

@Configuration 
    @ComponentScan(basePackages = "your package") 
    @EnableTransactionManagement 
    public class DatabaseConfig { 

     protected static final String PROPERTY_NAME_DATABASE_DRIVER = "com.mysql.jdbc.Driver"; 
     protected static final String PROPERTY_NAME_DATABASE_PASSWORD = "password"; 
     protected static final String PROPERTY_NAME_DATABASE_URL = "jdbc:mysql://localhost:3306/databasename"; 
     protected static final String PROPERTY_NAME_DATABASE_USERNAME = "login"; 

     private static final String PROPERTY_PACKAGES_TO_SCAN = "where your models are"; 
     @Bean 
     public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter){ 
      LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 
      entityManagerFactoryBean.setDataSource(dataSource); 
      entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter); 
      entityManagerFactoryBean.setPackagesToScan(PROPERTY_PACKAGES_TO_SCAN); 
      return entityManagerFactoryBean; 
     } 

     @Bean 
     public BasicDataSource dataSource(){ 
      BasicDataSource ds = new BasicDataSource(); 
      ds.setDriverClassName(PROPERTY_NAME_DATABASE_DRIVER); 
      ds.setUrl(PROPERTY_NAME_DATABASE_URL); 
      ds.setUsername(PROPERTY_NAME_DATABASE_USERNAME); 
      ds.setPassword(PROPERTY_NAME_DATABASE_PASSWORD); 
      ds.setInitialSize(5); 
      return ds; 
     } 

     @Bean 
     public JpaVendorAdapter jpaVendorAdapter(){ 
      HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); 
      adapter.setDatabase(Database.MYSQL); 
      adapter.setShowSql(true); 
      adapter.setGenerateDdl(true); 

//I'm using MySQL5InnoDBDialect to make my tables support foreign keys 
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); 
      return adapter; 
     } 

     @Bean 
     public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { 
      return new JpaTransactionManager(entityManagerFactory); 
     } 


    } 
+0

Tôi nhận được cùng một ngoại lệ và tôi đang sử dụng chú thích ngay từ đầu. Tôi đã giải quyết vấn đề bằng cách thêm @EnableTransactionManagement từ ví dụ này. Cảm ơn. – pram

+0

Vâng, cùng ở đây (cần @EnableTransactionManagement) nhưng tôi cũng lượm lặt một cái nugget từ câu trả lời này - một thiết lập tốt hơn cho đậu của tôi - Tôi đã cung cấp các bộ định cư của LocalContainerEntityManagerFactoryBean cho dataSource và jpaVendorAdapter với các cuộc gọi đến các phương thức bean được định nghĩa! đoán rằng đó là chống lại các hạt quản lý container và không chắc chắn về các tác dụng phụ nhưng tôi phải tất cả mọi thứ sau khi đọc này và các vấn đề của tôi đã biến mất: D – Psyrus

1

Chỉ cần xác nhận, việc thêm định nghĩa bean cuối cùng sẽ giải quyết được vấn đề này!

lớp cấu hình của tôi là như sau:

@Configuration 
@EnableTransactionManagement 
@ComponentScan 
public class OFSConfig { 

    @Bean 
    public IDAO<FuelStation> getFSService() { 
     return new FSService(); 
    } 

    @Bean 
    public LocalEntityManagerFactoryBean emfBean() { 
     LocalEntityManagerFactoryBean e = new LocalEntityManagerFactoryBean(); 
     e.setPersistenceUnitName("org.superbapps.db_OWSDB_PU"); 

     return e; 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager(EntityManagerFactory em) { 
     return new JpaTransactionManager(em); 
    } 
} 

Các dịch vụ chính nó là như sau:

@Transactional 
@Repository 
public class FSService implements IDAO<FuelStation> { 

    @PersistenceContext 
    private EntityManager EM; 

    public EntityManager getEM() { 
     return EM; 
    } 

    public void setEM(EntityManager EM) { 
     this.EM = EM; 
    } 

    @Override 
    public List<FuelStation> getAll() { 
     return EM.createNamedQuery("FuelStation.findAll") 
       .getResultList(); 
    } 

    @Override 
    public FuelStation getByID(String ID) { 
     FuelStation fs = (FuelStation) EM.createNamedQuery("FuelStation.findById") 
       .setParameter("id", ID) 
       .getSingleResult(); 

     return fs; 
    } 

    @Override 
    public void update(FuelStation entity) { 
     EM.merge(entity); 
    } 

} 
3

Tôi không biết nếu bất cứ ai đang đọc bài viết này (hôm nay) có trường hợp tương tự như của tôi, nhưng tôi đã có cùng một vấn đề. Luckly, tôi có thể sửa chữa nó bằng cách đơn giản đặt những điều sau đây trong tôi mùa xuân-conf.xml:

<beans xmlns="http://www.springframework.org/schema/beans" 
... 
xmlns:tx="http://www.springframework.org/schema/tx" 
... 
xsi:schemaLocation=" 
... 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx.xsd"> 

<bean id="tManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
<property name="entityManagerFactory" ref="emf" /> 
</bean> 

<!-- This does the trick! --> 
<tx:annotation-driven transaction-manager="tManager" /> 

Lưu ý: Tôi đang sử dụng các giao dịch khai báo thông qua các chú thích. Vì vậy, nếu bạn làm vậy, chú thích phương pháp của bạn với @Transactional cũng có thể giải quyết vấn đề của bạn.

THAM KHẢO:

  1. http://blog.jhades.org/how-does-spring-transactional-really-work/
  2. http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/transaction.html
Các vấn đề liên quan