使用 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 并获得所有这些代码