2015-09-14 16 views
11

Tôi đang sử dụng JPA trong ứng dụng của mình, và nó hoạt động khi tôi truy vấn đối tượng, tuy nhiên nó ném lỗi javax.persistence.TransactionRequiredException: No transactional EntityManager available sau khi tôi cố gắng lưu hoặc cập nhật một đối tượng.Không thể lưu/cập nhật thực thể bằng JPA vào mùa xuân

Đây là cấu hình java:

@Configuration 
@EnableTransactionManagement(proxyTargetClass = true) 
@PropertySource("classpath:dao.properties") 
public class JpaConfig { 
    @Autowired 
    private Environment env; 
    @Bean 
    public DataSource dataSource() { 
     BasicDataSource dataSource = new BasicDataSource(); 
     ..................... 
     return dataSource; 
    } 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
     Properties jpaProperties = new Properties(); 
     jpaProperties.put("hibernate.dialect", ...........) 

     LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 
     entityManagerFactoryBean.setDataSource(dataSource()); 
     entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); 
     entityManagerFactoryBean.setJpaProperties(jpaProperties); 
     entityManagerFactoryBean.setPackagesToScan("com...."); 
     return entityManagerFactoryBean; 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) { 
     JpaTransactionManager transactionManager = new JpaTransactionManager(); 
     transactionManager.setEntityManagerFactory(emf); 
     return transactionManager; 
    } 
} 

Lưu ý tôi sử dụng proxyTargetClass = true trong @EnableTransactionManagement, vì tôi không muốn để tạo ra các giao diện vô dụng trong ứng dụng của tôi.

Và đây là implemention cụ thể của dao:

@Transactional 
@Repository 
public abstract class AbstractJPADao<I, E> { 
    @Autowired 
    @PersistenceContext 
    protected EntityManager entityManager; 

    private Class<E> type; 
    public AbstractJPADao() { 
     type=.... 
    } 

    @Override 
    public Result<E> find(I id) { 
     E e = entityManager.find(type, id); 
     return Result.newInstance().setContent(e); 
    } 

    @Override 
    public Result<E> find(Map<String, Object> condition) { 
     Query q = entityManager.createQuery(".......)); 
     return Result.newInstance().setContent(q.getResultList()); 
    } 

    @Override 
    public E save(E element) { 
     entityManager.persist(element); 
     return element; 
    } 
    @Override 
    public E update(E element) { 
     entityManager.merge(element); 
     return element; 
    } 

    @Override 
    public void delete(E element) { 
     entityManager.remove(element); 
    } 
} 

@Repository 
@Transactional 
public class DepartmentDao extends AbstractJPADao<String, Department> { 
    @Override 
    protected String selectCause(Map<String, Object> condition) { 
     return ""; 
    } 
} 

Và bộ điều khiển như khách hàng của dao:

@Controller 
@RequestMapping("/api/deps") 
public class DepartmentCtrl { 
    @Autowired 
    private DepartmentDao departmentDao; 
    @RequestMapping(value = "", method = RequestMethod.POST) 
    public Result create(@Valid Department department, BindingResult bindingResult) { 
     if (!bindingResult.hasErrors()) { 
      departmentDao.save(department); 
      return Result.newInstance().setContent(department); 
     } 
     throw new RuntimeException("..."); 
    } 
} 

Có gì không ổn?


dao.properties:

jdbc.driverClassName=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql://localhost:3306/proj 
jdbc.username=root 
jdbc.password= 

hibernate.dialect=org.hibernate.dialect.MySQL5Dialect 
hibernate.hbm2ddl.auto=update 
#hibernate.ejb.naming_strategy=true 
hibernate.show_sql=true 
hibernate.format_sql=true 
+1

Tại sao có hai chú thích '@ Autowired' và' @ PersistenceContext' trên trường 'protected' của loại' EntityManager' trong 'AbstractJPADao'? – Tiny

+0

'EntityManager' được cung cấp trong' JpaConfig' như một bean sẽ được đưa vào 'AbstractJPADao'. – hguser

+0

Bạn đang chạy bộ chứa nào? –

Trả lời

4

Hãy thử đổi tên phương pháp transactionManager để txManager trong lớp JpaConfig

Autowiring trôi qua tên txManager

Chỉnh sửa

Ngoài ra, khung làm việc có thể được mong đợi là không có phương pháp đối số cho txManager. bạn có thể thử thay đổi để

@Bean 
public PlatformTransactionManager transactionManager() { 
    JpaTransactionManager transactionManager = new JpaTransactionManager(); 
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); 
    return transactionManager; 
} 
+0

Nó không hoạt động. – hguser

+0

@hguser Đã chỉnh sửa câu trả lời của tôi. Bạn có thể thử không? – gipsy

+0

Cảm ơn, tôi đã thử: loại bỏ các đối số trong phương thức và sử dụng cả hai 'transactionManager' và 'txManager' làm tên phương thức. Không ai trong số họ làm việc. : ( – hguser

1

Như nhận thấy Tiny, bạn có hai chú thích @Autowired và @PersistenceContext trong lĩnh vực bảo vệ của loại EntityManager trong AbstractJPADao. Thử xóa @Autowired. @PersistenceContext là đủ để tiêm EntityManager.

+0

Không khắc phục được điều đó. – hguser

Các vấn đề liên quan