我试图在Spring中创建REST API,并且需要仅使用JavaConfig通过JPA建立数据库连接。这是我的配置类:
@Configuration
@ComponentScan
@EnableTransactionManagement
public class ApplicationConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.backend.domain", "com.backend.infrastructure.persistence" } );
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
em.afterPropertiesSet();
return em;
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername( "root" );
dataSource.setPassword( "root" );
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.format_sql", "true");
return properties;
}
}
我有一个自定义存储库实现:
@Repository
@Transactional
public class GenericRepositoryImpl<K, E> implements GenericRepository<K, E> {
protected static final Logger LOG = LoggerFactory.getLogger(GenericRepositoryImpl.class);
private Class<E> entityClass;
@PersistenceContext()
protected EntityManager entityManager;
@SuppressWarnings("unchecked")
public GenericRepositoryImpl() {
ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[0];
}
public void start() throws DomainException {
try {
entityManager.getTransaction().begin();
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
public void commit() throws DomainException {
try {
entityManager.getTransaction().commit();
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public void detach(E entity) throws DomainException {
try {
entityManager.detach(entity);
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public E findById(K id) throws DomainException {
try {
return entityManager.find(entityClass, id);
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public E findLockedEntityById(K id) throws DomainException {
try {
return entityManager.find(entityClass, id, LockModeType.OPTIMISTIC);
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public void persist(E entity) throws DomainException {
try {
entityManager.persist(entity);
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public E merge(E entity) throws DomainException {
try {
return entityManager.merge(entity);
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public void flush() throws DomainException {
try {
entityManager.flush();
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public void remove(E entity) throws DomainException {
try {
entityManager.remove(entity);
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public void refresh(E entity) throws DomainException {
try {
entityManager.refresh(entity);
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public void refreshLockedEntity(E entity) throws DomainException {
try {
entityManager.refresh(entity, LockModeType.OPTIMISTIC);
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
@Override
public void lock(E entity) throws DomainException {
try {
entityManager.lock(entity, LockModeType.OPTIMISTIC);
} catch (Exception e) {
LOG.error(e.getMessage());
throw new DomainException(e);
}
}
}
它正确编译,我可以看到数据库连接已建立,但在尝试保存实体时,会调用merge()方法并抛出NullPointerException。我在这里做错了什么?
提前致谢