0

我有一个难题。我正在使用 spring-security-acl 和他们的 jdbc 实现。问题是,我在其他查询中使用 JPA 存储库(Spring-data-jpa)。我认为,这没问题,因为 JPA 已实现:

<jpa:repositories base-package="cz.repository" />

  <beans:bean id="myEmf"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      <beans:property name="dataSource" ref="dataSource" />
      <beans:property name="packagesToScan" value="cz.models" />
      <beans:property name="jpaVendorAdapter">
          <beans:bean
              class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>

      </beans:property>
      <beans:property name="jpaProperties">
          <beans:props>

              <beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
              </beans:prop>
              <beans:prop key="hibernate.show_sql">true</beans:prop>
          </beans:props>
      </beans:property>
  </beans:bean>

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

所以我在这个 JPA 中已经有了数据源,直接使用 JDBC 的 spring-security 没有问题。

但问题在于交易

我在用

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

但是spring-acl jdbc想要

  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

当我想对我的项目实施 ACL 时,我:

@Transactional
@PreAuthorize("permitAll")
public Room createRoom(Integer roomID) {
    // TODO Auto-generated method stub
    createAcl(roomID);
    return roomRepository.save(roomID);

}

但我使用@Transactional

org.springframework.orm.jpa.JpaTransactionManager

而不是 jdbc

org.springframework.jdbc.datasource.DataSourceTransactionManager

不经常,但有时我有:

java.lang.IllegalArgumentException: Transaction must be running
at org.springframework.util.Assert.isTrue(Assert.java:65)
    at org.springframework.security.acls.jdbc.JdbcMutableAclService.createOrRetrieveSidPrimaryKey(JdbcMutableAclService.java:218)
    at org.springframework.security.acls.jdbc.JdbcMutableAclService.createObjectIdentity(JdbcMutableAclService.java:152)
    at org.springframework.security.acls.jdbc.JdbcMutableAclService.createAcl(JdbcMutableAclService.java:107)
    at cz.services.RepositoryRoomService.createAcl(RepositoryRoomService.java:118)

我对 JDBC 的事务没有那么深入的了解,所以会有问题添加

org.springframework.jdbc.datasource.DataSourceTransactionManager

并有两个事务管理器?还有另一个选项是编写我自己的 acl 服务而不是 JdbcMutableAclService。但是使用 jdbc 是更简单的解决方案。

<beans:bean id="aclService"
        class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
        <beans:constructor-arg ref="dataSource" />
        <beans:constructor-arg ref="lookupStrategy" />
        <beans:constructor-arg ref="aclCache" />
    </beans:bean>

有人可以告诉我什么更好吗?

或者将 JDBC 与 JPA 结合使用不是很好的解决方案并且只使用其中一种技术?感谢您的回答

4

1 回答 1

1

我建议不要在两个事务管理器中使用相同的事务管理器名称,考虑更改其中一个的 id

<beans:bean id="transactionManager"

<beans:bean id="transactionManagerJPA"  

然后

@Transactional("transactionManagerJPA") 

或者考虑用标记你的方法@TransactionalAttribute(TransactionAttributeType.REQUIRES_NEW)

于 2014-02-25T15:02:41.017 回答