这根本不是关于Spring靴的。
我的英语可以更好。
使用下面的Spring Data配置,我正在尝试执行DML请求。
恰好是< code>CrudRepository#save方法。
然而,执行Spring的CrudRepository#保存方法,我接下来要做的是:
hibernate.show_sql
功能记录。====================================================
不确定,但它看起来像一个交易问题。
当时似乎没有交易,
因此,在事务之外,CRUD Repos无法执行DML请求,包括CrudRepository#sav
。
也许是配置有问题?请看看,并随时询问任何其他信息。
更新:下一个不良实践解决方法帮助我实现了“更新”语句的执行。
//(autowired, shared entity manager)
entityManager.joinTransaction();
repository.save(user);
然而,这仍然是一种糟糕的做法。在这种情况下,Spring失去了作用。无论如何,我需要使用基于声明性代码的交易管理。问题仍然悬而未决:我的配置有什么问题@事务注释仍然不起作用
用户域实体:
@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;
}
特定于域的Spring Data CRUD Repository声明:
public interface UserRepository extends CrudRepository<User, Integer> {
//nothing specific
}
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;
}
}
我不明白,你是如何初始化数据源属性的?我在你给定的代码中看不到。
factory.setDataSource(dataSource());
您应该设计如下配置类。同时使用 :
entityManagerFactoryRef="entityManagerFactory",
transactionManagerRef="jpaTransactionManager"
从 yaml 或属性文件中读取Hibernate属性。
并设置您的数据源
配置类:DataConfig
/**
* @author Som
*
*/
@Configuration
@EnableJpaRepositories(basePackages="package-name",
entityManagerFactoryRef="entityManagerFactory",
transactionManagerRef="jpaTransactionManager")
@EnableTransactionManagement
@PropertySource(value = { "classpath:application.yml" })
public class DataConfig {
@Autowired
private Environment environment;
@Value("${datasource.myapp.maxPoolSize:10}")
private int maxPoolSize;
/**
* Populate DataSourceProperties object directly from application.yml
* *
*/
@Bean
@Primary
@ConfigurationProperties(prefix = "datasource.myapp")
public DataSourceProperties dataSourceProperties(){
return new DataSourceProperties();
}
/**
* Configure HikariCP pooled DataSource.
*
*/
@Bean
public DataSource dataSource() {
DataSourceProperties dataSourceProperties = dataSourceProperties();
HikariDataSource dataSource = (HikariDataSource) DataSourceBuilder
.create(dataSourceProperties.getClassLoader())
.driverClassName(dataSourceProperties.getDriverClassName())
.url(dataSourceProperties.getUrl())
.username(dataSourceProperties.getUsername())
.password(dataSourceProperties.getPassword())
.type(HikariDataSource.class)
.build();
dataSource.setMaximumPoolSize(maxPoolSize);
return dataSource;
}
/**
* Entity Manager Factory setup.
*
*/
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setPackagesToScan(new String[] { "package-name" });
factoryBean.setJpaVendorAdapter(jpaVendorAdapter());
factoryBean.setJpaProperties(jpaProperties());
return factoryBean;
}
/**
* Provider specific adapter.
*
*/
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
return hibernateJpaVendorAdapter;
}
/**
* Hibernate properties.
*
*/
private Properties jpaProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("datasource.myapp.hibernate.dialect"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("datasource.myapp.hibernate.hbm2ddl.method"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("datasource.myapp.hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("datasource.myapp.hibernate.format_sql"));
if(StringUtils.isNotEmpty(environment.getRequiredProperty("datasource.myapp.defaultSchema"))){
properties.put("hibernate.default_schema", environment.getRequiredProperty("datasource.myapp.defaultSchema"));
}
return properties;
}
@Bean
@Autowired
public PlatformTransactionManager jpaTransactionManager(EntityManagerFactory emf) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(emf);
return txManager;
}
}
应用程序.yaml
server:
port: 8081
servlet:
context-path: /CRUDApp
---
spring:
profiles: local,default
datasource:
myapp:
url: jdbc:h2:~/test
username: SA
password:
driverClassName: org.h2.Driver
defaultSchema:
maxPoolSize: 10
hibernate:
hbm2ddl.method: create-drop
show_sql: true
format_sql: true
dialect: org.hibernate.dialect.H2Dialect
---
终于,我找到了解决我的问题的办法。
因为我使用的Spring没有启动部分,所以我必须配置定制的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
}
}
因此,由于我已经使用注释配置Web应用程序#注册了两个配置类(WebApp配置.class,数据配置.class),所以我认为用@Configuration注释配置将是Redundand。
当时我错了。
要正确注册事务管理器,您应该使用@Configuration来注释您的 Jpa 配置类。
因此,我设法用@Configuration注释了我的配置类,这解决了我的问题。
现在,SpringCRUDRepositories能够对数据库运行DML查询(借助#save方法)。确切地说:现在存储库能够打开自己的事务并根据这些事务运行所需的查询。
我试图创建一些切入点和之前的建议为存储库,以便能够在Spring启动的Spring数据中过滤一些存储库的实体管理器。我在项目中也有Web和服务层,AounLogging适用于两者。但是我不能为存储库做同样的事情。我已经挣扎了2天,我尝试了很多东西来修复它。我几乎阅读了关于此的每个文档、问题和线程(代理问题CGlib和JDK代理等)。我使用jhipster创建项目。 除了@Pointcut和Crud
我需要使用spring@Cacheable注释缓存对MongoDB的调用: 不幸的是,使用@Cacheable注释接口中的任何方法都会导致以下异常: 我正在寻找一种方法来缓存对DB的调用(这相当昂贵)。有什么想法吗?
我在使用JPA时遇到了一些困难。我没有得到任何异常,但我不能保存任何东西到数据库。我从Hibernate到Jpa,在那里一切都工作得很好。下面是我的文件 Application.Properties: 存储库: 服务: 我在提交表单时得到了200的响应,但在数据库中找不到数据
我正在使用Spring Batch和JPA处理一个批处理作业并执行更新。我正在使用默认的存储库实现。 并且我正在使用一个repository.save将修改后的对象保存在处理器中。而且,我没有在处理器或编写器中指定任何@Transactional注释。 下面是我的步骤,读取器和写入器配置:另外,我的config类是用EnableBatchProcessing注释的 在writer中,这就是我使用的
我有一个数据已经保存在我的数据库基于我的存储库和服务。我想保存另一个数据与邮递员只改变播放器id。但它不是创建一个新的实体数据。它更新现有的实体数据。我的问题是如何更新一个数据由我的服务当它找到一个现有的id。但当它找到一个新的id将保存一个新的数据到数据库。 这是我的回购: 这是我的服务: