Spring(v 3.1)WebアプリケーションでscalaでプログラムされたBeanを使用しようとしましたが、トランザクションに関して奇妙な問題が発生しました。
問題を示すために、Rooで小さいながらも完全なSpringアプリケーションをセットアップしました。正直なところ、なぜ機能しないのかわかりません...
project --topLevelPackage com.app
jpa setup --provider ECLIPSELINK --database DERBY_EMBEDDED
entity jpa --class com.app.MyEntity
field string --fieldName title
次に、Javaでインターフェイスを作成しました
package com.app;
public interface IScalaMainClass {
void doSomething();
}
package com.app;
public interface IScala1 {
void someMethod();
}
package com.app;
public interface IScala2 {
void someMethod();
}
実装はScalaで作成され、Scala1はMyEntityを永続化し、Scala2はDELETEクエリを実行します。
package com.app
import org.springframework.transaction.annotation.Transactional
import org.springframework.stereotype.Repository
import org.springframework.beans.factory.annotation.Autowired
@Repository class ScalaMainClass extends com.app.IScalaMainClass {
@Autowired var bean1: IScala1 = null
@Autowired var bean2: IScala2 = null
@Transactional def doSomething() = {
bean1.someMethod()
bean2.someMethod()
}
}
package com.app
import org.springframework.stereotype.Repository
import javax.persistence.{EntityManager, PersistenceContext}
@Repository class Scala1 extends com.app.IScala1 {
@PersistenceContext var em: EntityManager = null
def someMethod = {
val e = new MyEntity
em persist e
}
}
package com.app
import org.springframework.transaction.annotation.Transactional
import org.springframework.stereotype.Repository
import javax.persistence.{EntityManager, PersistenceContext}
@Repository class Scala2 extends com.app.IScala2 {
@PersistenceContext var em: EntityManager = null
@Transactional def someMethod = {
val q = em createQuery "DELETE FROM MyEntity"
q executeUpdate
}
}
最後に、IScalaMainClassを実行するJavaのテストが作成されます。
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.test.annotation.Rollback;
import org.springframework.beans.factory.annotation.Autowired;
import org.junit.runner.RunWith;
import org.junit.Test;
import org.junit.Assert;
import com.app.IScalaMainClass;
@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(defaultRollback = false)
public class AppTest {
@Autowired private IScalaMainClass smc;
@Test public void testIt() {
smc.doSomething();
}
}
ここでscalaの依存関係をpom.xmlに追加し、「mvn test」を実行すると、次のようになります。
javax.persistence.TransactionRequiredException:
Exception Description: No transaction is currently active
...