【发布时间】:2018-09-05 18:34:11
【问题描述】:
我在尝试将实体添加到数据库时遇到错误。我已经推荐了this。但它没有太多关于我的问题的信息
我有一个用于管理获取、保存和更新实体的 EJB jar。
这是我的远程 ejb
@Remote
public abstract interface DatalayerService{
public abstract void add(Object object)
}
这是实现
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class DatalayerServiceImpl implements DatalayerService{
@PersistenceContext(name="myPersistenceUnit")
EntityManager em = null;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void add(Object object) throws FatalException{
try {
em.persist(object);
}
catch (Throwable e){
throw manageDatalayerError(e);
}
finally {
}
}
}
我正在尝试在我的应用程序中使用上述 ejb
1)
@ComponentScan({"com.springboot"})
@EnableJpaRepositories
@SpringBootApplication
public class SpringEjbApplication extends SpringBootServletInitializer{
public static void main(String args[]){
SpringApplication.run(SpringApplication.class,args);
}
@Bean
public DatalayerService datalayerService() throws NamingException{
return new DatalayerServiceImpl();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException{
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[]{"com.springboot.pojo"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setPersistenceProviderClass(HibernatePersistenceProvider.class);
em.setJpaVendorAdapter(vendorAdapter);
em.setPersistenceUnitName("myPersistenceUnit");
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public DataSource dataSource() throws NamingException{
return (DataSource) new JndiTemplate().lookup("openejb:Resource/MyDataSource");
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
private Properties additionalProperties(){
Properties properties = new Properties();
properties.setProperty("hibernate.max_fetch_depth", "3");
properties.setProperty("hibernate.default_batch_fetch_size", "2");
properties.setProperty("hibernate.jdbc.batch_size", "100");
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.format_sql", "false");
return properties;
}
}
2)休息服务
@RestController
public class HomeEndPoint{
@Autowired
private IUserService iUserService;
@GetMapping("/createUser")
@Transactional(rollbackFor = {ServiceExpectedException.class,FatalException.class,MandatoryParameterMissingFatalException.class})
public void createUser() throws FatalException,ServiceExpectedException{
iUserService.createUser();
}
}
3)用户服务及其实现
public interface IUserService{
public void createUser() throws FatalException;
}
@Service
@Transactional(rollbackFor = {ServiceExpectedException.class,FatalException.class,MandatoryParameterMissingFatalException.class})
public class UserServiceImpl implements IUserService{
@Autowired
private DatalayerGenericService datalayerGenericService;
@Override
public void createUser() throws FatalException,ServiceExpectedException{
Team team = new Team(simpleContextService);
team.setGroupName("MyTeam");
team.setStoreId(100);
// Team
datalayerGenericService.add(team);
Log.info(this,"add team ");
// Build user1
datalayerGenericService.add(user1);
Log.info(this,"############################# Added User1 ######################################");
// Build user2
datalayerGenericService.add(user2);
Log.info(this,"############################# Added User2 ######################################");
}
}
我尝试使用 url 运行其余服务
http://localhost:6180/SpringBootDatalayer/createUser
我收到以下异常。
信息:(com.edifixio.springboot.service.impl.UserServiceImpl)
###################### teamOid 20 信息:(com.edifixio.springboot.service.impl.UserServiceImpl) ###################### 添加用户1######################## ############ 信息:(com.edifixio.springboot.service.impl.UserServiceImpl) ###################### 添加了用户2 ######################## ############ 信息:http-nio-6180-exec-1:AbstractBatchImpl.release:HHH000010:在批次发布时它仍然包含 JDBC 语句 2018-03-27 16:28:17,683:错误: http-nio-6180-exec-1:BatchingBatch.performExecution:HHH000315: 执行批处理的异常[java.sql.BatchUpdateException:批处理条目 0 插入 TEAM (CREATE_TIMESTAMP, PROJECT_GROUP_NAME, LAST_UPDATE_TIMESTAMP、STORE_ID、ID)值('2018-3-27 16:28:17.447000 +5:30:0','MMA_TEST','2018-3-27 16:28:17.503000 +5:30:0', 100, 21) 被中止。调用 getNextException 查看原因。], SQL: insert into TEAM (CREATE_TIMESTAMP, PROJECT_GROUP_NAME, LAST_UPDATE_TIMESTAMP、STORE_ID、ID)值(?、?、?、?、?)
从异常中可以看出,它是使用 datalayerGenericService 创建团队、用户 1 和用户 2。但尝试再次执行以给出 AbstractBatchImpl.release : HHH000010: 在批处理发布时它仍然包含 JDBC 语句。
这是我得到的例外:
java.sql.BatchUpdateException:批处理条目 1 插入 TEAM (CREATE_TIMESTAMP、PROJECT_GROUP_NAME、LAST_UPDATE_TIMESTAMP、 STORE_ID, ID) 值 ('2018-3-29 12:9:26.611000 +5:30:0', 'MMA_TEST', '2018-3-29 12:9:26.836000 +5:30:0', 100, 23) 被中止。称呼 getNextException 来查看原因。
我该如何解决这个问题?为什么查询会执行两次?
如果 EJB 方法发生任何异常,它应该回滚事务。但它没有发生
注意:如果我从服务中删除 @Transactional 注释,它可以正常工作。 我使用的是 TomEE 7.0.2 服务器。
【问题讨论】:
-
您已将事务指定为
NOT_SUPPORTED,因此不会启动任何事务。请改用REQUIRED。此外,这里不涉及 EJB 内容,无论您添加了这些注释。 Spring 不会启动 EJB 容器,因此它只是一个普通的 Spring bean。 -
方法中有注解@TransactionAttribute(TransactionAttributeType.REQUIRED)。所以这里涉及到 EJB 的东西。
-
不,没有...您只是在使用默认事务注释,它不会使其成为 EJB。添加所有这些接口和注释不会给您带来任何好处,只会增加 Spring 默默忽略的代码的复杂性和开销(除了
Transactional,因为 spring 确实支持这一点)。 -
那么,如果我理解你的评论,你是说 DatalayerServiceImpl 不是 EJB?
-
正确,它只是一个 Spring Bean。 Spring 不是 EJB 容器...
标签: spring spring-boot jpa transactions ejb-3.0