spring querydsl我不想开始交易

时间:2016-12-08 08:18:12

标签: spring jpa querydsl

实体:

package com.test.entity

@Entity
@Table(name="TEST_TABLE")
public class TestTable implements HasMapping, PrimaryKey<Long>, Serializable {
public static final String TABLE_NAME = "TEST_TABLE";

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ID", nullable=false)
    private Long id;

    @Id
    @Column(name="Name", nullable=false)
    private String name;

    @Temporal(value=TemporalType.TIMESTAMP)
    @Column(name="CREATE_TIME", nullable=true)
    @CreatedDate
    private Date createTime;

    @Column(name="CREATE_USER", nullable=true, length=32)
    @CreatedBy
    private String createUser;

    @Temporal(value=TemporalType.TIMESTAMP)
    @Column(name="LST_UPD_TIME", nullable=true)
    @LastModifiedDate
    private Date lstUpdTime;

    @Column(name="LST_UPD_USER", nullable=true, length=32)
    @LastModifiedBy
    private String lstUpdUser;

    @Column(name="JPA_VERSION", nullable=false)
    @Version
    private Integer jpaVersion;
    ......
}

QPath

package com.test.qpath

@Generated("com.mysema.query.codegen.EntitySerializer")
public class QTestTable extends EntityPathBase<TestTable> {

    private static final long serialVersionUID = -1751805455;

    public static final QTestTable testTable = new QTestTable("testTable");

    public final NumberPath<Long> id = createNumber("id", Long.class);

    public final DateTimePath<java.util.Date> createTime = createDateTime("createTime", java.util.Date.class);

    public final StringPath createUser = createString("createUser");

    public final NumberPath<Integer> jpaVersion = createNumber("jpaVersion", Integer.class);

    public final DateTimePath<java.util.Date> lstUpdTime = createDateTime("lstUpdTime", java.util.Date.class);

    public final StringPath lstUpdUser = createString("lstUpdUser");

    public QTestTable(String variable) {
        super(TestTable.class, forVariable(variable));
    }

    @SuppressWarnings("all")
    public QTestTable(Path<? extends TestTable> path) {
        super((Class)path.getType(), path.getMetadata());
    }

    public QTestTable(PathMetadata<?> metadata) {
        super(TestTable.class, metadata);
    }
    ......
}

存储库

package com.test.repos

public interface RTestTable extends JpaRepository<TestTable, Long>, QueryDslPredicateExecutor<TestTable> {
}

服务

package com.test.service

@Service
public class TestServiceR() {
    @Autowired
    private RTestTable rTestTable;
    public void handler() {
        long id = 1;
        TestTable t = rTestTable.findone(id);
    }
}


package com.test.service

@Service
public class TestServiceQuery() {
    @Autowired
    private RTestTable rTestTable;
    @PersistenceContext
    private EntityManager em;
    private QTestTable qTestTable = QTestTable.testTable;
    public void handler() {
        long id = 1;
        JPAQuery query = new JPAQuery(em);
        TestTable t = query.from(qTestTable).where(qTestTable.id.eq(id)).singleResult(qTestTable);
    }
}

spring config

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
    <property name="url" value="#{env.jdbcUrl}" />
    <property name="username" value="#{env.jdbcUsername}" />
    <property name="password" value="#{env.jdbcPassword}" />
    <property name="initialSize" value="1" />
    <property name="minIdle" value="#{env['jdbcMinIdle'] ?: 2 }" />
    <property name="maxActive" value="#{env['jdbcMaxActive'] ?: 20}" />
    <property name="minEvictableIdleTimeMillis" value="#{env['jdbcMinEvictableIdleTimeMillis'] ?: 1800000}" />
    <property name="validationQuery" value="#{env['jdbcTestSql']}" />
    <property name="testWhileIdle" value="#{env['jdbcTestWhileIdle']?: false}" />
    <property name="testOnBorrow" value="#{env['jdbcTestOnBorrow']?: true}" />
    <property name="testOnReturn" value="#{env['jdbcTestOnReturn']?: false}" />
    <property name="poolPreparedStatements" value="false" />
    <property name="maxPoolPreparedStatementPerConnectionSize" value="-1" />
    <property name="filters" value="mergeStat,slf4j" />
    <property name="connectionProperties" value="druid.stat.slowSqlMillis=1500;druid.stat.logSlowSql=true" />
    <property name="timeBetweenLogStatsMillis" value="900000" />
</bean>
<bean id="emf"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="persistenceUnitName" value="default" />
    <property name="packagesToScan">
        <list>
            <value>com.sunline.ccs.infrastructure.shared.model</value>
        </list>
    </property>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="database" value="#{env['jpaDatabaseType']?:'DEFAULT'}" />
            <property name="showSql" value="#{env['jpaShowSql']?:false}" />
        </bean>
    </property>
</bean>

<bean id="sessionFactory" factory-bean="emf" factory-method="getSessionFactory" />

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="emf" />
</bean>

<tx:annotation-driven mode="aspectj"
    transaction-manager="transactionManager" />

<jpa:repositories base-package="com.test.repos" />

我测试TestServiceR.handler()和TestServiceQuery.handler()。 我认为他们不会开始交易。 但是类TestServiceR正在启动一个事务。 为什么?如何设置TestServiceR.handler()不启动事务。

1 个答案:

答案 0 :(得分:0)

TestServiceR调用RTestTable.findOneJpaRepository扩展SimpleJpaRepository,由@Transactional(readOnly = true)实施,注释时使用SimpleJpaRepository。因此,交易由@EnableJpaRepositories(enableDefaultTransactions = false)启动。

是否有一个特殊原因让您担心交易,因为它不会对应用产生负面影响(至少不会太多)?如果您不相信,请参阅this Spring Data JPA JIRA issue的评论记录。

如果您仍想覆盖默认行为,可以将JPA存储库初始化为<jpa:repositories enable-default-transactions="false" ... />(Java配置)或mapDispatchToProps(XML配置),以防止默认实现默认情况下创建事务。有关详细信息,请参阅this Spring Data JPA JIRA issue