使用 Spring 批处理(和 Spring-Admin)业务逻辑数据不持久
Business logic Data not persist using Spring Batch (and Spring-Admin)
我正在使用 Spring-batch Spring-batch-admin 和 Spring-boot
我定义了存储库并创建了基本实体
但是,当我执行 save(..) 时,我检查了我的数据库 table 并且没有任何内容被保留。除了一些调试日志外,也不会抛出错误:
2015-01-12 12:21:12.652 DEBUG 13692 --- [nio-8080-exec-1] stomAnnotationTransactionAttributeSource : Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2015-01-12 12:21:12.653 DEBUG 13692 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'transactionManager'
2015-01-12 12:21:12.678 DEBUG 13692 --- [nio-8080-exec-1] o.s.j.d.DataSourceTransactionManager : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2015-01-12 12:21:12.683 DEBUG 13692 --- [nio-8080-exec-1] o.s.j.d.DataSourceTransactionManager : Acquired Connection [jdbc:mysql://localhost:3306/spring_batch_test, UserName=root@localhost, MySQL Connector Java] for JDBC transaction
2015-01-12 12:21:12.693 DEBUG 13692 --- [nio-8080-exec-1] o.s.j.d.DataSourceTransactionManager : Switching JDBC Connection [jdbc:mysql://localhost:3306/spring_batch_test, UserName=root@localhost, MySQL Connector Java] to manual commit
2015-01-12 12:21:12.816 DEBUG 13692 --- [nio-8080-exec-1] ataPostProcessor$ThreadBoundTargetSource : Initializing lazy target object
Gradle 建造:
buildscript {
repositories {
maven { url 'http://artifactory/artifactory/libs-release-local' }
mavenCentral()
maven { url 'http://repo.spring.io/milestone/' }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.0.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
war {
baseName = 'notification-processor-service'
version = '1.0.0-SNAPSHOT'
}
jar {
baseName = 'notification-processor-service'
version = '1.0.0-SNAPSHOT'
}
ext {
springIntegrationKafkaVersion = '1.0.0.M2'
}
repositories {
maven { url 'http://artifactory/artifactory/libs-release-local' }
maven { url 'http://artifactory/artifactory/resin-hessian' }
mavenCentral()
maven {
url 'https://repository.apache.org/content/groups/public'
}
maven { url 'http://repo.spring.io/milestone/' }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("com.caucho:resin-hessian:4.0.23")
compile("mysql:mysql-connector-java")
compile('org.springframework.boot:spring-boot-starter-web:1.2.0.RELEASE')
compile("org.springframework.boot:spring-boot-starter-batch:1.2.0.RELEASE")
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("javax.inject:javax.inject:1")
compile('org.springframework.batch:spring-batch-admin-manager:1.3.0.RELEASE') {
exclude module: 'slf4j-log4j12'
}
testCompile('org.springframework.boot:spring-boot-starter-test:1.2.0.RELEASE')
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
Application.class:
package com.mycompany.notification.processor.service.main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* Created by Ext_IdanF on 25/12/2014.
*/
@ComponentScan({"com.mycompany.notification.processor.service"})
@EnableAutoConfiguration
@Configuration
@EntityScan({"com.mycompany.notification.processor.service.entities"})
@ImportResource({
"classpath:integration-context.xml", "classpath:launch-context.xml", "classpath:applicationContext-NotificationProcessorService.xml"
})
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.mycompany.notification.processor.service.dao"})
//@Import({ ServletConfiguration.class, WebappConfiguration.class })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
System.out.printf("hello man");
}
}
Spring批量配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--<context:property-placeholder location="classpath:batch-mysql.properties,
file:///d:/etc/mycompany/services/pushExecuterService/pushExecuterServices.properties"
ignore-unresolvable="true"
/>
-->
<bean id="jobBuilderFactory" class="org.springframework.batch.core.configuration.annotation.JobBuilderFactory">
<constructor-arg ref="jobRepository"/>
</bean>
<bean id="stepBuilderFactory" class="org.springframework.batch.core.configuration.annotation.StepBuilderFactory">
<constructor-arg index="0" ref="jobRepository"/>
<constructor-arg index="1" ref="transactionManager"/>
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${batch.jdbc.driver}"/>
<property name="url" value="${batch.jdbc.url}"/>
<property name="username" value="${batch.jdbc.user}"/>
<property name="password" value="${batch.jdbc.password}"/>
</bean>
<bean id="jobOperator"
class="org.springframework.batch.core.launch.support.SimpleJobOperator"
p:jobLauncher-ref="jobLauncher" p:jobExplorer-ref="jobExplorer"
p:jobRepository-ref="jobRepository" p:jobRegistry-ref="jobRegistry"/>
<bean id="jobExplorer"
class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
p:dataSource-ref="dataSource"/>
<bean id="jobRegistry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry"/>
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry"/>
</bean>
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
</beans>
这是批处理-mysql.properties:
# GENERAL:
batch.jdbc.testWhileIdle=true
batch.business.schema.script=classpath:/business-schema.sql
# Set to False to stop the database from being wiped and re-created.
batch.data.source.init=false
batch.schema=spring_batch_test
# MySQL:
batch.jdbc.driver=com.mysql.jdbc.Driver
batch.jdbc.url=jdbc:mysql://localhost:3306/spring_batch_test
batch.jdbc.user=root
batch.jdbc.password=root
batch.jdbc.validationQuery=SELECT 1
batch.schema.script=classpath:/org/springframework/batch/core/schema-mysql.sql
batch.drop.script=classpath*:/org/springframework/batch/core/schema-drop-mysql.sql
batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementr
和application.propteties
#LOGS PROPS
logging.level.com.mycompany.notification.processor.service: DEBUG
logging.level.org.springframework : DEBUG
logging.level.org.springframework.integration : INFO
#SPRING BATCH
spring.batch.job.enabled=false
#SPRING-BOOT
spring.freemarker.check-template-location=false
spring.velocity.checkTemplateLocation=false
server.servletPath=/*
spring.datasource.url=jdbc:mysql://localhost:3306/spring_batch_test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#DB
ENVIRONMENT=mysql
#TOMCAT
server.port=8080
恐怕我在 spring-batch && spring-batch-admin && spring 引导配置之间发生了一些冲突
我在 batch-mysql.proprties 中定义了 jdbc 道具,也在 application.properties
中定义了
顺便说一句:Spring-batch-admin 设法将数据库写入它自己的 tables
我添加了 Spring jpa 支持,但这次我得到了不同的错误:
No transactional EntityManager available
新 类:
public class AbstractJpaDAO<T, PK extends Serializable> {
@PersistenceContext
protected EntityManager entityManager;
...
public interface NotificationDao {
NotificationJobEntity save(NotificationJobEntity entity);
}
执行代码:
@Override
public NotificationJobEntity save(final NotificationJobEntity entity) {
super.persist(entity);
logger.debug("Persist a Notification entity in persistence store with Job-ID {}", entity.getJobId());
return entity;
}
谢谢
我不确定这是否正确
我所做的是使用 Spring JPA
已添加实体管理器
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="default" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
并使用 AbstractJpaDAO
这样:
public class AbstractJpaDAO<T, PK extends Serializable> {
@PersistenceContext
protected EntityManager entityManager;
private Class<T> persistentClass;
protected AbstractJpaDAO(final Class<T> persistentClass) {
this.persistentClass = persistentClass;
}
public void persist(T entity) {
entityManager.persist(entity);
}
public void update(T entity) {
entityManager.merge(entity);
}
public T find(PK pk, Class<T> t) {
return entityManager.find(t, pk);
}
public void delete(T entity) {
entityManager.remove(entity);
}
@SuppressWarnings("unchecked")
public Collection<T> findAll() {
return this.entityManager.createQuery("select obj from " + this.persistentClass.getName() + " obj").getResultList();
}
@SuppressWarnings("unchecked")
public Collection<T> findAll(int page, int pageSize) {
TypedQuery<T> query = (TypedQuery<T>) entityManager.createQuery("select obj from " + this.persistentClass.getName() + " obj");
query.setFirstResult(page * pageSize);
query.setMaxResults(pageSize);
return query.getResultList();
}
}
太糟糕了,我无法找到一种方法来使用 Spring-data 并获得所有这些代码
我正在使用 Spring-batch Spring-batch-admin 和 Spring-boot
我定义了存储库并创建了基本实体 但是,当我执行 save(..) 时,我检查了我的数据库 table 并且没有任何内容被保留。除了一些调试日志外,也不会抛出错误:
2015-01-12 12:21:12.652 DEBUG 13692 --- [nio-8080-exec-1] stomAnnotationTransactionAttributeSource : Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2015-01-12 12:21:12.653 DEBUG 13692 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'transactionManager'
2015-01-12 12:21:12.678 DEBUG 13692 --- [nio-8080-exec-1] o.s.j.d.DataSourceTransactionManager : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2015-01-12 12:21:12.683 DEBUG 13692 --- [nio-8080-exec-1] o.s.j.d.DataSourceTransactionManager : Acquired Connection [jdbc:mysql://localhost:3306/spring_batch_test, UserName=root@localhost, MySQL Connector Java] for JDBC transaction
2015-01-12 12:21:12.693 DEBUG 13692 --- [nio-8080-exec-1] o.s.j.d.DataSourceTransactionManager : Switching JDBC Connection [jdbc:mysql://localhost:3306/spring_batch_test, UserName=root@localhost, MySQL Connector Java] to manual commit
2015-01-12 12:21:12.816 DEBUG 13692 --- [nio-8080-exec-1] ataPostProcessor$ThreadBoundTargetSource : Initializing lazy target object
Gradle 建造:
buildscript {
repositories {
maven { url 'http://artifactory/artifactory/libs-release-local' }
mavenCentral()
maven { url 'http://repo.spring.io/milestone/' }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.0.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
war {
baseName = 'notification-processor-service'
version = '1.0.0-SNAPSHOT'
}
jar {
baseName = 'notification-processor-service'
version = '1.0.0-SNAPSHOT'
}
ext {
springIntegrationKafkaVersion = '1.0.0.M2'
}
repositories {
maven { url 'http://artifactory/artifactory/libs-release-local' }
maven { url 'http://artifactory/artifactory/resin-hessian' }
mavenCentral()
maven {
url 'https://repository.apache.org/content/groups/public'
}
maven { url 'http://repo.spring.io/milestone/' }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("com.caucho:resin-hessian:4.0.23")
compile("mysql:mysql-connector-java")
compile('org.springframework.boot:spring-boot-starter-web:1.2.0.RELEASE')
compile("org.springframework.boot:spring-boot-starter-batch:1.2.0.RELEASE")
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("javax.inject:javax.inject:1")
compile('org.springframework.batch:spring-batch-admin-manager:1.3.0.RELEASE') {
exclude module: 'slf4j-log4j12'
}
testCompile('org.springframework.boot:spring-boot-starter-test:1.2.0.RELEASE')
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
Application.class:
package com.mycompany.notification.processor.service.main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* Created by Ext_IdanF on 25/12/2014.
*/
@ComponentScan({"com.mycompany.notification.processor.service"})
@EnableAutoConfiguration
@Configuration
@EntityScan({"com.mycompany.notification.processor.service.entities"})
@ImportResource({
"classpath:integration-context.xml", "classpath:launch-context.xml", "classpath:applicationContext-NotificationProcessorService.xml"
})
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.mycompany.notification.processor.service.dao"})
//@Import({ ServletConfiguration.class, WebappConfiguration.class })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
System.out.printf("hello man");
}
}
Spring批量配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--<context:property-placeholder location="classpath:batch-mysql.properties,
file:///d:/etc/mycompany/services/pushExecuterService/pushExecuterServices.properties"
ignore-unresolvable="true"
/>
-->
<bean id="jobBuilderFactory" class="org.springframework.batch.core.configuration.annotation.JobBuilderFactory">
<constructor-arg ref="jobRepository"/>
</bean>
<bean id="stepBuilderFactory" class="org.springframework.batch.core.configuration.annotation.StepBuilderFactory">
<constructor-arg index="0" ref="jobRepository"/>
<constructor-arg index="1" ref="transactionManager"/>
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${batch.jdbc.driver}"/>
<property name="url" value="${batch.jdbc.url}"/>
<property name="username" value="${batch.jdbc.user}"/>
<property name="password" value="${batch.jdbc.password}"/>
</bean>
<bean id="jobOperator"
class="org.springframework.batch.core.launch.support.SimpleJobOperator"
p:jobLauncher-ref="jobLauncher" p:jobExplorer-ref="jobExplorer"
p:jobRepository-ref="jobRepository" p:jobRegistry-ref="jobRegistry"/>
<bean id="jobExplorer"
class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
p:dataSource-ref="dataSource"/>
<bean id="jobRegistry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry"/>
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry"/>
</bean>
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
</beans>
这是批处理-mysql.properties:
# GENERAL:
batch.jdbc.testWhileIdle=true
batch.business.schema.script=classpath:/business-schema.sql
# Set to False to stop the database from being wiped and re-created.
batch.data.source.init=false
batch.schema=spring_batch_test
# MySQL:
batch.jdbc.driver=com.mysql.jdbc.Driver
batch.jdbc.url=jdbc:mysql://localhost:3306/spring_batch_test
batch.jdbc.user=root
batch.jdbc.password=root
batch.jdbc.validationQuery=SELECT 1
batch.schema.script=classpath:/org/springframework/batch/core/schema-mysql.sql
batch.drop.script=classpath*:/org/springframework/batch/core/schema-drop-mysql.sql
batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementr
和application.propteties
#LOGS PROPS
logging.level.com.mycompany.notification.processor.service: DEBUG
logging.level.org.springframework : DEBUG
logging.level.org.springframework.integration : INFO
#SPRING BATCH
spring.batch.job.enabled=false
#SPRING-BOOT
spring.freemarker.check-template-location=false
spring.velocity.checkTemplateLocation=false
server.servletPath=/*
spring.datasource.url=jdbc:mysql://localhost:3306/spring_batch_test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#DB
ENVIRONMENT=mysql
#TOMCAT
server.port=8080
恐怕我在 spring-batch && spring-batch-admin && spring 引导配置之间发生了一些冲突
我在 batch-mysql.proprties 中定义了 jdbc 道具,也在 application.properties
中定义了顺便说一句:Spring-batch-admin 设法将数据库写入它自己的 tables
我添加了 Spring jpa 支持,但这次我得到了不同的错误:
No transactional EntityManager available
新 类:
public class AbstractJpaDAO<T, PK extends Serializable> {
@PersistenceContext
protected EntityManager entityManager;
...
public interface NotificationDao {
NotificationJobEntity save(NotificationJobEntity entity);
}
执行代码:
@Override
public NotificationJobEntity save(final NotificationJobEntity entity) {
super.persist(entity);
logger.debug("Persist a Notification entity in persistence store with Job-ID {}", entity.getJobId());
return entity;
}
谢谢
我不确定这是否正确 我所做的是使用 Spring JPA
已添加实体管理器
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="default" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
并使用 AbstractJpaDAO 这样:
public class AbstractJpaDAO<T, PK extends Serializable> {
@PersistenceContext
protected EntityManager entityManager;
private Class<T> persistentClass;
protected AbstractJpaDAO(final Class<T> persistentClass) {
this.persistentClass = persistentClass;
}
public void persist(T entity) {
entityManager.persist(entity);
}
public void update(T entity) {
entityManager.merge(entity);
}
public T find(PK pk, Class<T> t) {
return entityManager.find(t, pk);
}
public void delete(T entity) {
entityManager.remove(entity);
}
@SuppressWarnings("unchecked")
public Collection<T> findAll() {
return this.entityManager.createQuery("select obj from " + this.persistentClass.getName() + " obj").getResultList();
}
@SuppressWarnings("unchecked")
public Collection<T> findAll(int page, int pageSize) {
TypedQuery<T> query = (TypedQuery<T>) entityManager.createQuery("select obj from " + this.persistentClass.getName() + " obj");
query.setFirstResult(page * pageSize);
query.setMaxResults(pageSize);
return query.getResultList();
}
}
太糟糕了,我无法找到一种方法来使用 Spring-data 并获得所有这些代码