gpt4 book ai didi

java - [查询DSL/Spring]java.lang.IllegalStateException : Connection is not transactional

转载 作者:搜寻专家 更新时间:2023-10-31 20:01:00 27 4
gpt4 key购买 nike

我正在编写 Spring+Vaadin 应用程序。我想添加 QueryDSL 来访问数据库 (Oracle)。我查看了文档 (http://docs.spring.io/spring-data/jdbc/docs/current/reference/html/core.querydsl.html),我读到 Spring 推荐使用标准的 QueryDSL api。我根据依赖项改进了我的项目:

<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-sql-spring</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-sql</artifactId>
<version>${querydsl.version}</version>
</dependency>

我的beans.xml如下:

<bean id="dataSourceOracle" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.oracle.driverClassName}" />
<property name="url" value="${db.oracle.url}"/>
<property name="username" value="${db.oracle.username}" />
<property name="password" value="${db.oracle.password}" />
<property name="defaultAutoCommit" value="false" />
</bean>

在我的 DatabaseFacade 实现中,我做了以下配置:

private SQLQueryFactory query;

@Autowired
@Qualifier("DataSource")
public void setDataSource(DataSource dataSource) {
Provider<Connection> provider = new SpringConnectionProvider(dataSource);
Configuration configuration = new Configuration(new OracleTemplates());
configuration.setExceptionTranslator(new SpringExceptionTranslator());
query = new SQLQueryFactory(configuration, provider);
}

不幸的是,每次我启动应用程序时,我都会得到:

10:29:54.490 [main] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
10:29:56.231 [main] ERROR c.r.i.k.b.impl.DatabaseFacadeImpl - Error happend in com.roche.icc.kps.backend.impl.DatabaseFacadeImpl.getEditableKPSStores
10:29:56.234 [main] ERROR c.r.i.k.b.impl.DatabaseFacadeImpl - Connection is not transactional
java.lang.IllegalStateException: Connection is not transactional
at com.mysema.query.sql.spring.SpringConnectionProvider.get(SpringConnectionProvider.java:45) ~[querydsl-sql-spring-3.7.0.jar:na]
at com.mysema.query.sql.spring.SpringConnectionProvider.get(SpringConnectionProvider.java:33) ~[querydsl-sql-spring-3.7.0.jar:na]
at com.mysema.query.sql.SQLQueryFactory.query(SQLQueryFactory.java:63) ~[querydsl-sql-3.7.0.jar:na]
at com.mysema.query.sql.SQLQueryFactory.query(SQLQueryFactory.java:28) ~[querydsl-sql-3.7.0.jar:na]
at com.mysema.query.sql.AbstractSQLQueryFactory.from(AbstractSQLQueryFactory.java:54) ~[querydsl-sql-3.7.0.jar:na]

有人遇到过这个问题吗?我是否应该使用不同的 DataSource(Atomikos?)?

感谢您的帮助!

卡米尔

最佳答案

我遇到了同样的问题。

问题是 QueryDSL 期望数据源连接处于事务中。因此,要么您必须显式开始事务并处理它,要么 IOC 容器应该为您完成。

在这种情况下,您很可能在本应启动事务的任何应用程序层(服务/存储库)中都没有@Transactional 注释。

将@Transactional 注释添加到您的 dao 或服务层以解决问题。

对我有帮助的链接是 https://groups.google.com/forum/#!topic/querydsl/_PqMek79TZE

一个示例项目。 https://github.com/querydsl/querydsl/tree/master/querydsl-examples/querydsl-example-sql-spring

更新

这就是示例项目中的 DaoImpl。
注意类级别的@Transactional 注释。

@Transactional
public class CustomerDaoImpl implements CustomerDao {

@Inject
SQLQueryFactory queryFactory;

final QBean<CustomerAddress> customerAddressBean = bean(CustomerAddress.class,
customerAddress.addressTypeCode, customerAddress.fromDate, customerAddress.toDate,
bean(Address.class, address.all()).as("address"));

final QBean<Customer> customerBean = bean(Customer.class,
customer.id, customer.name,
bean(Person.class, person.all()).as("contactPerson"),
GroupBy.set(customerAddressBean).as("addresses"));

@Override
public Customer findById(long id) {
List<Customer> customers = findAll(customer.id.eq(id));
return customers.isEmpty() ? null : customers.get(0);
}

@Override
public List<Customer> findAll(Predicate... where) {
return queryFactory.from(customer)
.leftJoin(customer.contactPersonFk, person)
.leftJoin(customer._customer3Fk, customerAddress)
.leftJoin(customerAddress.addressFk, address)
.where(where)
.transform(GroupBy.groupBy(customer.id).list(customerBean));
}

@Override
public Customer save(Customer c) {
Long id = c.getId();

if (id == null) {
id = queryFactory.insert(customer)
.set(customer.name, c.getName())
.set(customer.contactPersonId, c.getContactPerson().getId())
.executeWithKey(customer.id);
c.setId(id);
} else {
queryFactory.update(customer)
.set(customer.name, c.getName())
.set(customer.contactPersonId, c.getContactPerson().getId())
.where(customer.id.eq(c.getId()))
.execute();

// delete address rows
queryFactory.delete(customerAddress)
.where(customerAddress.customerId.eq(id))
.execute();
}

SQLInsertClause insert = queryFactory.insert(customerAddress);
for (CustomerAddress ca : c.getAddresses()) {
if (ca.getAddress().getId() == null) {
ca.getAddress().setId(queryFactory.insert(address)
.populate(ca.getAddress())
.executeWithKey(address.id));
}
insert.set(customerAddress.customerId, id)
.set(customerAddress.addressId, ca.getAddress().getId())
.set(customerAddress.addressTypeCode, ca.getAddressTypeCode())
.set(customerAddress.fromDate, ca.getFromDate())
.set(customerAddress.toDate, ca.getToDate())
.addBatch();
}
insert.execute();

c.setId(id);
return c;
}

@Override
public long count() {
return queryFactory.from(customer).fetchCount();
}

@Override
public void delete(Customer c) {
// TODO use combined delete clause
queryFactory.delete(customerAddress)
.where(customerAddress.customerId.eq(c.getId()))
.execute();

queryFactory.delete(customer)
.where(customer.id.eq(c.getId()))
.execute();
}

}

在您的情况下,注释应放置在您的 DatabaseFacade 实现中。我假设您的 Spring 应用程序也配置了事务管理器。

关于java - [查询DSL/Spring]java.lang.IllegalStateException : Connection is not transactional,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34198920/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com