簡単な質問: Spring で Bean として宣言されていないクラスで Spring のトランザクション マネージャーを使用するにはどうすればよいですか (または可能ですか)。
詳細... Spring 3 と Hibernate 3.6 を使用するアプリケーションと、次のような 2 つのクラスがあります。
public class FooManagerImpl implements FooManager {
@Override
@Transactional
public Foo getFoo(int id) {
Session s = sessionFactory.getCurrentSession();
// do some query
return foo;
}
}
FooManagerImpl
Spring Bean (以下を参照) ですが、FooImpl
そうではありません。 FooImpl
エンティティでもある 3 番目のクラス との親子関係がBar
あります (ここで問題が発生します)。
@Entity
@Table(name = "foo_table")
public class FooImpl implements Foo {
private List<Bar> bars;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SELECT)
@JoinColumn(name = "foo_id", referencedColumnName = "foo_id")
public List<Bar> getBar() {
return this.bars; // Bar is also an entity
}
public void addBar(Bar b) {
this.bar.add(b);
}
}
そして、Spring 構成の関連部分:
<tx:annotation-driven />
<jee:jndi-lookup id="fooDatasource" jndi-name="fooDatasource" />
<bean id="fooSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="fooDatasource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
</props>
</property>
<property name="packagesToScan">
<value>com.foo</value>
</property>
</bean>
<bean id="fooTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="fooSessionFactory" />
<qualifier value="ec" />
</bean>
<bean id="fooManager" class="com.foo.model.FooManagerImpl">
<property name="sessionFactory" ref="fooSessionFactory" />
</bean>
私が理解しているように、を呼び出すとFooImpl.addBar(Bar)
、Hibernate は変更を永続化しようとしますが、トランザクションがバインドされていないため失敗します。FooImpl
Spring はBean ではないため、Spring はメソッドのいずれもプロキシしないため、TX バウンドはありません。それは正しい評価ですか?これを機能させる方法はありますか?
これまでに見つけた解決策ですが、うまく機能していないようです (または、機能させることができません)。
こちらのように、AOP プロキシをセットアップしてトランザクション アドバイスを挿入します。しかし、私が知る限り、これらのプロキシは、クラスを Bean として定義した場合にのみ適用されますよね?
などのAspectJも使用できると思います
<tx:annotation-driven mode="aspectj"/>
が、それには別のクラスローダーを使用する必要があるようです. . ここを参照してください。私は OpenSessionInView を使いたくありません。なぜなら、サービス レイヤーの外でバックエンド トランザクションが発生するという考えがあまり好きではないからです。
だから、私は困惑しています。誰にもアイデアはありますか?私が試したことのいずれかがすでに機能している必要がありますか? (たぶん私はそれを台無しにしました。)
前もって感謝します。