2015-09-14 120 views
11

我在我的應用程序中使用JPA,它在我查詢對象後工作,但是一旦我嘗試保存或更新對象時會拋出錯誤javax.persistence.TransactionRequiredException: No transactional EntityManager available無法使用JPA在彈簧中保存/更新實體

這是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; 
    } 
} 

注意我在@EnableTransactionManagement使用proxyTargetClass = true,因爲我不希望在我的應用程序來創建無用的接口。

這是道的具體FPGA實現:

@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 ""; 
    } 
} 

而控制器作爲道的客戶端:

@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("..."); 
    } 
} 

這有什麼錯?


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

爲什麼'AbstractJPADao'中有兩個註解'@ Autowired'和'@ PersistenceContext' 'EntityManager'類型的'protected'字段? – Tiny

+0

''JpaConfig'中提供'EntityManager'作爲一個bean,應該被注入'AbstractJPADao'。 – hguser

+0

你在哪個容器中運行? –

回答

4

嘗試在類JpaConfig

自動裝配推移名稱重命名方法transactionManagertxManagertxManager

編輯

此外,框架可能期望txManager的無參數方法。你可以嘗試改變,以

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

它不起作用。 – hguser

+0

@hguser編輯我的答案。你可以試試嗎? – gipsy

+0

謝謝,我已經嘗試過:刪除方法中的參數,並使用'transactionManager'和'txManager'作爲方法名稱。他們都沒有工作。 :( – hguser

1

由於注意到微小的,你有兩個註解@Autowired和@PersistenceContext了在AbstractJPADao型的EntityManager的保護領域。 嘗試刪除@Autowired。 @PersistenceContext足以注入EntityManager。

+0

不解決這個問題。 – hguser

相關問題