Spring CrudRepository delete() 什么都不做
Spring CrudRepository delete() does nothing
在单元测试期间,我试图通过 Spring 的 CrudRepository 从我的数据库中删除一个条目,但似乎什么也没发生。
实体:
@Entity @Table(name = "FACTION")
public class Faction implements Serializable
{
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", columnDefinition = "int", nullable = false, unique = true)
private Integer id;
public Integer getId()
{
return this.id;
}
}
存储库:
public interface FactionDao extends CrudRepository<Faction, Integer>
{
}
我的测试class:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Config.class)
@Sql({ "/delete-testData.sql", "/insert-testData.sql" })
public class TestFactionDao
{
@Autowired
private FactionDao dao;
@Test
public void testDelete()
{
System.out.println(this.dao.findOne(1));
this.dao.delete(1);
System.out.println(this.dao.findOne(1));
}
}
Spring配置:
@Configuration
@EnableJpaRepositories(basePackageClasses = Config.class)
@EnableTransactionManagement
public class Config
{
@Bean
public DataSource dataSource()
{
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
}
@Bean
public PlatformTransactionManager transactionManager(DataSource pDataSource)
{
return new DataSourceTransactionManager(pDataSource);
}
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource pDataSource)
{
HibernateJpaVendorAdapter tJpaVendorAdapter = new HibernateJpaVendorAdapter();
tJpaVendorAdapter.setDatabase(Database.H2);
tJpaVendorAdapter.setGenerateDdl(true);
tJpaVendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean tEntityManagerFactory = new LocalContainerEntityManagerFactoryBean();
tEntityManagerFactory.setJpaVendorAdapter(tJpaVendorAdapter);
tEntityManagerFactory.setDataSource(pDataSource);
tEntityManagerFactory.setPackagesToScan(Config.class.getPackage().getName());
return tEntityManagerFactory;
}
}
sql 脚本:
-- delete-testData.sql
delete from FACTION;
-- insert-testData.sql
insert into FACTION (ID) values
(1);
下面是测试用例期间的控制台输出。如您所见,没有执行删除操作,我仍然可以读取刚刚删除的实体:
Hibernate: create table FACTION (ID int generated by default as identity, primary key (ID))
Hibernate: select faction0_.ID as ID1_3_0_ from FACTION faction0_ where faction0_.ID=?
de.iavra.data.Faction@1b97f47
Hibernate: select faction0_.ID as ID1_3_0_ from FACTION faction0_ where faction0_.ID=?
Hibernate: select faction0_.ID as ID1_3_0_ from FACTION faction0_ where faction0_.ID=?
de.iavra.data.Faction@17b8fa4
我尝试用@Rollback(false) 注释我的测试方法,但它似乎没有任何区别。在 dao 上调用 flush() 会抛出一个异常,表示没有待处理的更新。
您必须为 update
和 delete
操作添加事务。
public class FactionService {
@Autowired
private FactionDao dao;
@Transactional
public void delete(int id){
dao.delete(id);
}
}
我测试了你的代码,解决方案是将 transactionManager 类型从 PlatformTransactionManager 更改为 JpaTransactionManager。 (我想也许 PlatformTransactionManager 只在函数结束时提交删除。)
所以代码是:
Config.java
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource pDataSource) {
HibernateJpaVendorAdapter tJpaVendorAdapter = new HibernateJpaVendorAdapter();
...
在单元测试期间,我试图通过 Spring 的 CrudRepository 从我的数据库中删除一个条目,但似乎什么也没发生。
实体:
@Entity @Table(name = "FACTION")
public class Faction implements Serializable
{
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", columnDefinition = "int", nullable = false, unique = true)
private Integer id;
public Integer getId()
{
return this.id;
}
}
存储库:
public interface FactionDao extends CrudRepository<Faction, Integer>
{
}
我的测试class:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Config.class)
@Sql({ "/delete-testData.sql", "/insert-testData.sql" })
public class TestFactionDao
{
@Autowired
private FactionDao dao;
@Test
public void testDelete()
{
System.out.println(this.dao.findOne(1));
this.dao.delete(1);
System.out.println(this.dao.findOne(1));
}
}
Spring配置:
@Configuration
@EnableJpaRepositories(basePackageClasses = Config.class)
@EnableTransactionManagement
public class Config
{
@Bean
public DataSource dataSource()
{
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
}
@Bean
public PlatformTransactionManager transactionManager(DataSource pDataSource)
{
return new DataSourceTransactionManager(pDataSource);
}
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource pDataSource)
{
HibernateJpaVendorAdapter tJpaVendorAdapter = new HibernateJpaVendorAdapter();
tJpaVendorAdapter.setDatabase(Database.H2);
tJpaVendorAdapter.setGenerateDdl(true);
tJpaVendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean tEntityManagerFactory = new LocalContainerEntityManagerFactoryBean();
tEntityManagerFactory.setJpaVendorAdapter(tJpaVendorAdapter);
tEntityManagerFactory.setDataSource(pDataSource);
tEntityManagerFactory.setPackagesToScan(Config.class.getPackage().getName());
return tEntityManagerFactory;
}
}
sql 脚本:
-- delete-testData.sql
delete from FACTION;
-- insert-testData.sql
insert into FACTION (ID) values
(1);
下面是测试用例期间的控制台输出。如您所见,没有执行删除操作,我仍然可以读取刚刚删除的实体:
Hibernate: create table FACTION (ID int generated by default as identity, primary key (ID))
Hibernate: select faction0_.ID as ID1_3_0_ from FACTION faction0_ where faction0_.ID=?
de.iavra.data.Faction@1b97f47
Hibernate: select faction0_.ID as ID1_3_0_ from FACTION faction0_ where faction0_.ID=?
Hibernate: select faction0_.ID as ID1_3_0_ from FACTION faction0_ where faction0_.ID=?
de.iavra.data.Faction@17b8fa4
我尝试用@Rollback(false) 注释我的测试方法,但它似乎没有任何区别。在 dao 上调用 flush() 会抛出一个异常,表示没有待处理的更新。
您必须为 update
和 delete
操作添加事务。
public class FactionService {
@Autowired
private FactionDao dao;
@Transactional
public void delete(int id){
dao.delete(id);
}
}
我测试了你的代码,解决方案是将 transactionManager 类型从 PlatformTransactionManager 更改为 JpaTransactionManager。 (我想也许 PlatformTransactionManager 只在函数结束时提交删除。)
所以代码是:
Config.java
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource pDataSource) {
HibernateJpaVendorAdapter tJpaVendorAdapter = new HibernateJpaVendorAdapter();
...