这根本与 Spring Boot 无关。
我的英语还可以更好。
使用下面的 Spring Data 配置我尝试执行 DML 请求。
确切的CrudRepository#save方法。
然而,执行 Spring 的 CrudRepository#save 方法我接下来会得到:
hibernate.show_sql。=================================================== ==
不确定,但看起来像是交易问题。
那个时候好像还没有交易,
因此事务外 CRUD Repos 无法执行 DML 请求,包括CrudRepository#save.
也许是配置有问题?请看一下,并随时询问任何其他信息。
更新: 下一个不良实践解决方法帮助我实现了“更新”语句的执行。
//(autowired, shared entity manager)
entityManager.joinTransaction();
repository.save(user);
Run Code Online (Sandbox Code Playgroud)
然而,这仍然是一种不好的做法。在这种情况下,Spring 的目的就失去了。无论如何,我需要使用基于声明性代码的事务管理。问题仍然存在: 我的配置有什么问题?@Transactional 注解仍然不起作用
用户域实体:
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@Entity
@Table(name = "users")
public class User
{
@Id
@Column(name = "id_pk", length = 11)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idPk;
@Column(name = "user_id", length = 25, nullable = false, unique = true)
private String userId;
@Column(name = "email_addr", length = 120)
private String email;
}
Run Code Online (Sandbox Code Playgroud)
特定领域的 Spring Data CRUD 存储库声明:
public interface UserRepository extends CrudRepository<User, Integer> {
//nothing specific
}
Run Code Online (Sandbox Code Playgroud)
Spring (无引导)基于代码的配置:
@EnableJpaRepositories(basePackages = "***",
transactionManagerRef = "jpaTransactionManager")
@EnableTransactionManagement
public class DataConfig
{
@Bean
public EntityManagerFactory entityManagerFactory()
{
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource());
factory.setPackagesToScan(DOMAIN_ENTITY_SCAN_PACKAGE);
factory.setJpaVendorAdapter(getVendorAdapter());
factory.afterPropertiesSet();
return factory.getObject();
}
private HibernateJpaVendorAdapter getVendorAdapter()
{
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(Boolean.TRUE);
return vendorAdapter;
}
@Bean
public JpaTransactionManager jpaTransactionManager()
{
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
txManager.afterPropertiesSet();
return txManager;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 2
最后,我为我的案例找到了解决方案。
由于我使用的 Spring 没有 Boot 部分,因此我必须配置自定义WebApplicationInitializer来让 Spring 管理应用程序入口点:
public class MainWebAppInitializer implements WebApplicationInitializer
{
@Override
public void onStartup(final ServletContext sc)
{
AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
root.register(WebAppConfiguration.class, DataConfig.class);
sc.addListener(new ContextLoaderListener(root));
...other not related code ommited
}
}
Run Code Online (Sandbox Code Playgroud)
因此,因为我已经使用AnnotationConfigWebApplicationContext#register注册了两个配置类( WebAppConfiguration.class、DataConfig.class ),所以我认为使用@Configuration 注释配置将是多余的。
那时我错了。
要正确注册TransactionManager ,您应该使用@Configuration注释您的 Jpa Config 类。
因此,我设法用@Configuration注释我的配置类,这解决了我的问题。
现在 Spring CRUD 存储库能够对数据库运行 DML 查询(在 #save 方法的帮助下)。准确地说:现在存储库能够打开自己的事务并根据这些事务运行所需的查询。
| 归档时间: |
|
| 查看次数: |
10558 次 |
| 最近记录: |