Spring数据REST,无法保存,可以select
Spring Data REST, cannot save, can select
我很困惑为什么我的 Spring 数据 REST 代码可以正常工作,但现在不行了。可能是配置问题,但我无法指出是什么。当我使用 AJAX 到 post 到端点时,我收到 500 错误 - java.lang.IllegalArgumentException: argument type mismatch
。当我从独立 java 尝试 repository.save()
时,我没有得到任何回应。另一方面,当我执行获取 API 或调用 repository.find()
时,我可以看到 Hibernate 正在显示选择。所以我知道我的数据库已连接。此外,我正在使用 Flyway,这些脚本可以毫无问题地插入。
我正在使用 Spring-Boot-Starter for Data-REST、Data-JPA 和 thymeleaf,所有版本都是 1.2。1.RELEASE。我认识到这可能是一个版本问题,但我将其保留在这里以最终与 Spring-Security-Kerberos 集成,我知道它可以与 Spring-Boot 的那个版本一起使用。至少,我还没有让它与更高版本的 Spring-Boot.
一起使用
我注意到的一些事情可能相关也可能不相关:
@Transactional
在上面我的 @RestRepositoryResource
没有区别
- 调用
repository.save()
时,返回的实体 ID 保持为 0(我的实体是自动生成的)
- 我所有的实体都存在这个问题,包括没有任何关系的实体
- 我从我的一个实体中删除了 unique=true 并不重要
我的存储库接口之一
@RepositoryRestResource(collectionResourceRel = "shifts", path = "shifts")
public interface ShiftRepository extends PagingAndSortingRepository<Shift, Long> {
List<Shift> findBySiteId(@Param("siteId") String siteId);
Shift findByShiftCode(@Param("shiftCode") String shiftCode);
}
我的存储库配置组件
@Component
public class RepositoryConfigDev {
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Bean
EventHandler eventHandler() {
return new EventHandler();
}
@Bean
DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(driverClassName);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.SQL_SERVER);
adapter.setDatabasePlatform("org.hibernate.dialect.SQLServer2012Dialect");
adapter.setShowSql(true);
adapter.setGenerateDdl(false);
return adapter;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
emfb.setJpaVendorAdapter(jpaVendorAdapter());
emfb.setDataSource(dataSource());
emfb.setPackagesToScan("package.model");
emfb.afterPropertiesSet();
return emfb;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory().getObject());
txManager.setRollbackOnCommitFailure(true);
return txManager;
}
}
所以在从头开始重建之后,我弄清楚了我做错了什么。问题出在 @RepositoryEventHandler
。因为我最初宣布 class 为
@RepositoryEventHandler(value={Class1.class, Class2.class})
public class RepoEvents {
....
}
什么时候应该
@RepositoryEventHandler
public class RepoEvents {
@HandleBeforeCreate(Class1.class)
public void beforeCreate1(Class1 c) { ... }
@HandleBeforeCreate(Class2.class)
public void beforeCreate2(Class2 c) { ... }
}
我很困惑为什么我的 Spring 数据 REST 代码可以正常工作,但现在不行了。可能是配置问题,但我无法指出是什么。当我使用 AJAX 到 post 到端点时,我收到 500 错误 - java.lang.IllegalArgumentException: argument type mismatch
。当我从独立 java 尝试 repository.save()
时,我没有得到任何回应。另一方面,当我执行获取 API 或调用 repository.find()
时,我可以看到 Hibernate 正在显示选择。所以我知道我的数据库已连接。此外,我正在使用 Flyway,这些脚本可以毫无问题地插入。
我正在使用 Spring-Boot-Starter for Data-REST、Data-JPA 和 thymeleaf,所有版本都是 1.2。1.RELEASE。我认识到这可能是一个版本问题,但我将其保留在这里以最终与 Spring-Security-Kerberos 集成,我知道它可以与 Spring-Boot 的那个版本一起使用。至少,我还没有让它与更高版本的 Spring-Boot.
一起使用我注意到的一些事情可能相关也可能不相关:
@Transactional
在上面我的@RestRepositoryResource
没有区别- 调用
repository.save()
时,返回的实体 ID 保持为 0(我的实体是自动生成的) - 我所有的实体都存在这个问题,包括没有任何关系的实体
- 我从我的一个实体中删除了 unique=true 并不重要
我的存储库接口之一
@RepositoryRestResource(collectionResourceRel = "shifts", path = "shifts")
public interface ShiftRepository extends PagingAndSortingRepository<Shift, Long> {
List<Shift> findBySiteId(@Param("siteId") String siteId);
Shift findByShiftCode(@Param("shiftCode") String shiftCode);
}
我的存储库配置组件
@Component
public class RepositoryConfigDev {
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Bean
EventHandler eventHandler() {
return new EventHandler();
}
@Bean
DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(driverClassName);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.SQL_SERVER);
adapter.setDatabasePlatform("org.hibernate.dialect.SQLServer2012Dialect");
adapter.setShowSql(true);
adapter.setGenerateDdl(false);
return adapter;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
emfb.setJpaVendorAdapter(jpaVendorAdapter());
emfb.setDataSource(dataSource());
emfb.setPackagesToScan("package.model");
emfb.afterPropertiesSet();
return emfb;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory().getObject());
txManager.setRollbackOnCommitFailure(true);
return txManager;
}
}
所以在从头开始重建之后,我弄清楚了我做错了什么。问题出在 @RepositoryEventHandler
。因为我最初宣布 class 为
@RepositoryEventHandler(value={Class1.class, Class2.class})
public class RepoEvents {
....
}
什么时候应该
@RepositoryEventHandler
public class RepoEvents {
@HandleBeforeCreate(Class1.class)
public void beforeCreate1(Class1 c) { ... }
@HandleBeforeCreate(Class2.class)
public void beforeCreate2(Class2 c) { ... }
}