åã«Java EE 6ã®ãšã£ããããšããããšã§ãJAX-RSãšEJBãšJPAãã€ãªããŠéã³ãŸãããããã®æã¯Readã粟äžæ¯ã§ããã
ã§ãä»åã¯å°ãèŠç¹ãå€ããŠã³ã³ãã管çãã©ã³ã¶ã¯ã·ã§ã³ãèŠãŠãããããªãšæããŸãã
ã¡ããã©ãã¡ãã«ããã¿ãªãªããŒããã
EJBで複数テーブル保存時の自動ロールバック挙動を確認してみました - Challenge Java EE !
ãããŸããããåãããŸãã
ãŸãããã®ãŸãŸã§ã¯ãªãã§ãããèšèªãScalaã«ãJSFãJAX-RSã«çœ®ãæããŠãèªåãªãã«æ°ã«ãªããšããã確èªãããããªãšã
ããŒãã«å®çŸ©ã¯ããããªæãã§ã
CREATE TABLE opportunity ( opportunity_id VARCHAR(3), opportunity_name VARCHAR(10), PRIMARY KEY(opportunity_id) ); CREATE TABLE quote ( quote_id VARCHAR(3), opportunity_id VARCHAR(3), quote_name VARCHAR(10), PRIMARY KEY(quote_id) );
å ã®ããã°ã«çŽæ¥å®çŸ©ãããããã§ã¯ãªãã§ããããšãããããããªãšããããªãšã
æ°žç¶æ§ãŠãããã®å®çŸ©ã
src/main/resources/META-INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="javaee6.web.pu" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:jboss/datasources/mysqlXaDs</jta-data-source> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> </properties> </persistence-unit> </persistence>
CDIã䜿ãã®ã§ã
src/main/webapp/WEB-INF/beans.xml
ã空ãã¡ã€ã«ã§äœæããŸãããããJava EE 7ã ãšãç¹ã«æžãããšããªããã°ãããªããªããã§ããâŠããŸããä»ã¯EE 6ã ãããããã§ããã©ãå¿ããªãããã«ããŠãããŸãããã
ãšã³ãã£ãã£ã®å®çŸ©ã
src/main/scala/javaee6/web/entity/Entities.scala
package javaee6.web.entity import scala.beans.BeanProperty import javax.persistence.{Column, Entity, Id, JoinColumn, OneToOne, Table} object Opportunity { def apply(opportunityId: String, opportunityName: String): Opportunity = { val opp = new Opportunity opp.opportunityId = opportunityId opp.opportunityName = opportunityName opp } } @SerialVersionUID(1L) @Entity @Table(name = "opportunity") class Opportunity extends Serializable { @Id @Column(name = "opportunity_id") @BeanProperty var opportunityId: String = _ @Column(name = "opportunity_name") @BeanProperty var opportunityName: String = _ @OneToOne @JoinColumn(name = "opportunity_id") var quote: Quote = _ } object Quote { def apply(quoteId: String, opportunityId: String, quoteName: String): Quote = { val qte = new Quote qte.quoteId = quoteId qte.opportunityId = opportunityId qte.quoteName = quoteName qte } } @SerialVersionUID(1L) @Entity @Table(name = "quote") class Quote extends Serializable { @Id @Column(name = "quote_id") @BeanProperty var quoteId: String = _ @Column(name = "opportunity_id") @BeanProperty var opportunityId: String = _ @Column(name = "quote_name") @BeanProperty var quoteName: String = _ }
CRUDãããã«ããã£ãŠãäžäœã¯ã©ã¹ãããã®ã§ããããå°ãã¢ã¬ã³ãžããŠè¿œå ã
src/main/scala/javaee6/web/service/ServiceSupport.scala
package javaee6.web.service import scala.annotation.tailrec import scala.collection.JavaConverters._ import java.lang.reflect.ParameterizedType import javax.persistence.{EntityManager, PersistenceContext} trait PersistenceUnitSupport { var entityManager: EntityManager } trait StandardPersistenceUnitSupport extends PersistenceUnitSupport { @PersistenceContext(unitName = "javaee6.web.pu") var entityManager: EntityManager = _ } abstract class ServiceSupport[T] { self: PersistenceUnitSupport => val entityClass: Class[T] = findClass(getClass) @tailrec private def findClass[A](clazz: Class[_]): Class[A] = if (clazz.getSuperclass == classOf[ServiceSupport[_]]) clazz .getGenericSuperclass .asInstanceOf[ParameterizedType] .getActualTypeArguments() .apply(0) .asInstanceOf[Class[A]] else findClass(clazz.getSuperclass) def create(entity: T): Unit = self.entityManager.persist(entity) def edit(entity: T): Unit = self.entityManager.merge(entity) def remove(entity: T): Unit = self.entityManager.remove(entityManager.merge(entity)) def find(id: Any): T = self.entityManager.find(entityClass, id) def findAll: Iterable[T] = self.entityManager .createQuery(s"SELECT e FROM ${entityClass.getSimpleName} e") .getResultList .asScala .asInstanceOf[Iterable[T]] }
å€æŽç¹ã¯EntityManagerã®å®çŸ©ããã£ã¡ã«æã£ãŠãã£ãã®ãšããµãã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã§ãšã³ãã£ãã£ã®Classã¯ã©ã¹ãæž¡ããªãã§ããããã«ããŸãããå ã¯NetBeansã®èªåçæãããã®ã§ããããã¡ãã¯æ®éã«æžããŠããã®ã§âŠã
ãã¡ãããã ãã«ããã£ããã©ãïŒ
ã§ãã¹ããŒãã¬ã¹ã»ã»ãã·ã§ã³Beanãã¡ãã£ãšç¢ºèªã®ããã«ããªãã¬ãŒã·ã§ã³ããŸãšããã¯ã©ã¹ãããŸããåŒçšå
ã®ããã°ã«ãããã£ããããŸãã
src/main/scala/javaee6/web/service/Services.scala
src/main/scala/javaee6/web/service/Services.scala package javaee6.web.service import scala.collection.JavaConverters._ import javax.ejb.{EJB, LocalBean, Stateless} import javaee6.web.entity.{Opportunity, Quote} @Stateless @LocalBean class TransactionService { @EJB var oppService: OpportunityService = _ @EJB var qteService: QuoteService = _ def saveOpportunityAndQuote(opp: Opportunity, qte: Quote): Unit = { qteService.create(qte) oppService.create(opp) } // saveQuoteã¡ãœããã®å®è£ 次第ã§ãããŒã«ããã¯ãããã©ããã決ãŸã def unsafeOpportunityAndQuote(opp: Opportunity, qte: Quote): Unit = { try { saveQuote(qte) } catch { case e:Exception => println(s"Exception Cause[$e]") e.printStackTrace } saveOpportunity(opp) } def saveOpportunity(opp: Opportunity): Unit = oppService.create(opp) def saveQuote(qte: Quote): Unit = { // qteService.unsafeCreate(qte) qteService.create(qte) throw new IllegalStateException("Opps!") } } @Stateless @LocalBean class OpportunityService extends ServiceSupport[Opportunity] with StandardPersistenceUnitSupport { def findAllOrderById: Iterable[Opportunity] = entityManager .createQuery("SELECT o From Opportunity o ORDER BY o.opportunityId") .getResultList .asScala .asInstanceOf[Iterable[Opportunity]] } @Stateless @LocalBean class QuoteService extends ServiceSupport[Quote] with StandardPersistenceUnitSupport { def unsafeCreate(qte: Quote): Unit = { create(qte) throw new IllegalStateException("Opps!") } }
JAX-RSã®ãªãœãŒã¹ã¯ã©ã¹ã
src/main/scala/javaee6/web/jaxrs/TransactionSubmitResource.scala
package javaee6.web.jaxrs import java.net.URI import javax.inject.Inject import javax.ws.rs.{Consumes, Encoded, GET, Path, POST, Produces} import javax.ws.rs.core.{Context, MediaType, MultivaluedMap, Response, UriBuilder, UriInfo} import javaee6.web.entity.{Opportunity, Quote} import javaee6.web.service.{OpportunityService, QuoteService, TransactionService} @Path("/trans") class TransactionSubmitResource { @Inject var transactionService: TransactionService = _ @Inject var oppService: OpportunityService = _ @Inject var qteService: QuoteService = _ @GET @Path("index") @Produces(Array(MediaType.TEXT_HTML)) def index(@Context uriInfo: UriInfo): Response = { val responseHtml = <html> <head> <meta charset="UTF-8" /> <title>Jaxrs & CMT</title> </head> <body> <h1>åè«äžèŠ§</h1> <a href={uriInfo.getBaseUriBuilder.path("/trans/add").build().toASCIIString}>æ°èŠç»é²ãž</a><br /> <table border="1"> <tr><th>åè«ID</th><th>åè«å</th><th>èŠç©ID</th><th>èŠç©å</th></tr> {oppService.findAllOrderById.map { o => <tr> <td>{o.opportunityId}</td> <td>{o.opportunityName}</td> <td>{o.quote.quoteId}</td> <td>{o.quote.quoteName}</td> </tr> }} </table> </body> </html> Response.ok(responseHtml.toString).build } @GET @Path("add") @Produces(Array(MediaType.TEXT_HTML)) def add(@Context uriInfo: UriInfo): Response = { val responseHtml = <html> <head> <meta charset="UTF-8" /> <title>Jaxrs & CMT</title> </head> <body> <form action={uriInfo.getBaseUriBuilder.path("/trans/submit").build().toASCIIString} method="post"> åè«IDïŒ <input name="oppId" type="text" /><br /> åè«åïŒ <input name="oppName" type="text" /><br /> èŠç©IDïŒ <input name="qteId" type="text" /><br /> èŠç©åïŒ <input name="qteName" type="text" /><br /> <input type="submit" value="ä¿å" /> </form> </body> </html> Response.ok(responseHtml.toString).build } @POST @Path("submit") @Consumes(Array(MediaType.APPLICATION_FORM_URLENCODED)) def submit(form: MultivaluedMap[String, String]): Response = { val opp = Opportunity(form.get("oppId").get(0), form.get("oppName").get(0)) val qte= Quote(form.get("qteId").get(0), opp.opportunityId, form.get("qteName").get(0)) transactionService.saveOpportunityAndQuote(opp, qte) //transactionService.unsafeOpportunityAndQuote(opp, qte) Response .status(Response.Status.MOVED_PERMANENTLY) .location(new URI("/trans/index")) .build } }
HTMLããã¿ããšScalaã®XMLãªãã©ã«ã§æžããŠããã®ã¯ããæå¬âŠã
ãããã€ãããªãœãŒã¹ã¯ã©ã¹ã決å®ããã¯ã©ã¹ã
src/main/scala/javaee6/web/jaxrs/TransactionalApplication.scala
package javaee6.web.jaxrs import scala.collection.JavaConverters._ import javax.ws.rs.ApplicationPath import javax.ws.rs.core.Application @ApplicationPath("rest") class TransactionalApplication extends Application { override def getClasses: java.util.Set[Class[_]] = Set[Class[_]](classOf[TransactionSubmitResource]).asJava }
ããšãJAX-RSã§HTML formã®ããŒã¿ãåãåã£ãæã«ãã©ãããŠãæååããã¡ããã®ã§ãServlet FilterãæžããŸããâŠã
src/main/scala/javaee6/web/filter/EncodingFilter.scala
package javaee6.web.filter import javax.servlet.{Filter, FilterChain, FilterConfig, ServletRequest, ServletResponse} import javax.servlet.annotation.WebFilter @WebFilter(Array("/*")) class EncodingFilter extends Filter { override def init(filterConfig: FilterConfig): Unit = () override def destroy(): Unit = () override def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = { req.setCharacterEncoding("UTF-8") chain.doFilter(req, res) } }
JBoss ASã®system-propertiesãšãã ãšãããŸãåããªãã£ãã§âŠã
ã§ãããããããã€ããŠèµ·åã
以äžã®URLã«ã¢ã¯ã»ã¹ãããšã
http://localhost:8080/javaee6-web/rest/trans/index
ããããç»é¢ãåºãã®ã§ããªã³ã¯ãæŒããŠé 次é·ç§»ããŠãããŸãã
ã§ããããªæãã§ç»é²ãããããã§ããã
ããã§æ°ã«ãªãã®ã¯ãäŸå€ãæãããããŒã«ããã¯ãããç¹ã§ãããã€ã³ã¿ãŒã»ãã¿ãŒãã©ãã«ããã£ãŠãããã§ããããªã®ã§ãJAX-RSã§ã®ç»é²éšåããã®åŸã§ããå€æŽã
//transactionService.saveOpportunityAndQuote(opp, qte)
transactionService.unsafeOpportunityAndQuote(opp, qte)
TransactionServiceã¯ã©ã¹ã®è©²åœã®å®è£ ã¯ããããªã£ãŠããã®ã§
// saveQuoteã¡ãœããã®å®è£ 次第ã§ãããŒã«ããã¯ãããã©ããã決ãŸã def unsafeOpportunityAndQuote(opp: Opportunity, qte: Quote): Unit = { try { saveQuote(qte) } catch { case e:Exception => println(s"Exception Cause[$e]") e.printStackTrace } saveOpportunity(opp) } def saveOpportunity(opp: Opportunity): Unit = oppService.create(opp) def saveQuote(qte: Quote): Unit = { // qteService.unsafeCreate(qte) qteService.create(qte) throw new IllegalStateException("Opps!") }
ãã®çµæã©ããªãããšããããšã§ãããçµè«ãããããšããŒã«ããã¯ããŸããã§ããã
ã¹ã¿ãã¯ãã¬ãŒã¹ãããŒã£ãšèŠããšããããªã£ãŠããŠ
16:09:44,361 ERROR [stderr] (http--127.0.0.1-8080-3) java.lang.IllegalStateException: Opps! 16:09:44,362 ERROR [stderr] (http--127.0.0.1-8080-3) at javaee6.web.service.TransactionService.saveQuote(Services.scala:41) 16:09:44,362 ERROR [stderr] (http--127.0.0.1-8080-3) at javaee6.web.service.TransactionService.unsafeOpportunityAndQuote(Services.scala:27) 16:09:44,363 ERROR [stderr] (http--127.0.0.1-8080-3) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 16:09:44,363 ERROR [stderr] (http--127.0.0.1-8080-3) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 16:09:44,363 ERROR [stderr] (http--127.0.0.1-8080-3) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 16:09:44,364 ERROR [stderr] (http--127.0.0.1-8080-3) at java.lang.reflect.Method.invoke(Method.java:606) 16:09:44,364 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.ee.component.ManagedReferenceMethodInterceptorFactory$ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptorFactory.java:72) 16:09:44,366 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) 16:09:44,366 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:374) 16:09:44,367 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:127) 16:09:44,367 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:135) 16:09:44,368 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:36) 16:09:44,368 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) 16:09:44,368 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) 16:09:44,369 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:36) 16:09:44,369 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) 16:09:44,370 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.jpa.interceptor.SBInvocationInterceptor.processInvocation(SBInvocationInterceptor.java:47) 16:09:44,370 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) 16:09:44,370 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:82) 16:09:44,371 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) 16:09:44,374 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21) 16:09:44,380 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) 16:09:44,380 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) 16:09:44,381 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:53) 16:09:44,381 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) 16:09:44,382 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.ejb3.component.pool.PooledInstanceInterceptor.processInvocation(PooledInstanceInterceptor.java:51) 16:09:44,382 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) 16:09:44,382 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:228) 16:09:44,388 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:304) 16:09:44,388 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190) 16:09:44,397 ERROR [stderr] (http--127.0.0.1-8080-3) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
ã³ã³ãã管çã®ãã©ã³ã¶ã¯ã·ã§ã³ã«ãªã£ãŠããã®ãæåã®EJBã¡ãœããã³ãŒã«ã ãã§ããã次ã¯ãæ®éã®ã¡ãœããåŒã³åºãã§ãã
16:09:44,361 ERROR [stderr] (http--127.0.0.1-8080-3) java.lang.IllegalStateException: Opps! 16:09:44,362 ERROR [stderr] (http--127.0.0.1-8080-3) at javaee6.web.service.TransactionService.saveQuote(Services.scala:41) 16:09:44,362 ERROR [stderr] (http--127.0.0.1-8080-3) at javaee6.web.service.TransactionService.unsafeOpportunityAndQuote(Services.scala:27)
Seasar2ã®AOPã䜿ã£ããã©ã³ã¶ã¯ã·ã§ã³ã ãšããã®æã®ãã¿ãŒã³ãããŒã«ããã¯ããŒã¯ãããŠããã®ã§ããªãã»ã©ãªãŒã£ãŠæãã§ããã
ããã§ããã²ãšã€ãsaveQuoteã¡ãœããã®å®è£ ããã®ããã«å€ããŠè©ŠããŠã¿ãŸããã
def saveQuote(qte: Quote): Unit = { qteService.unsafeCreate(qte) // qteService.create(qte) // throw new IllegalStateException("Opps!") }
ããã§ãQuoteService#unsafeCreateã¡ãœããã®å®è£ ã¯ããã®ãããªåœ¢ã«ãªã£ãŠããŸãã
def unsafeCreate(qte: Quote): Unit = { create(qte) throw new IllegalStateException("Opps!") }
ãã®å ŽåãããŒã«ããã¯ããŸããããŸãããã ãã¶ã°ã·ã£ã£ãšãããŸããæåã«ãQuoteService#unsafeCreateã«ã€ã³ã¿ãŒã»ããããããã©ã³ã¶ã¯ã·ã§ã³ããããŒã«ããã¯ãããããšã決ãŸããŸãã
22:47:51,084 INFO [stdout] (http--127.0.0.1-8080-1) Exception Cause[javax.ejb.EJBTransactionRolledbackException: Opps!] 22:47:51,085 ERROR [stderr] (http--127.0.0.1-8080-1) javax.ejb.EJBTransactionRolledbackException: Opps! 22:47:51,086 ERROR [stderr] (http--127.0.0.1-8080-1) at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:139) 22:47:51,087 ERROR [stderr] (http--127.0.0.1-8080-1) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:204) 22:47:51,099 ERROR [stderr] (http--127.0.0.1-8080-1) at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:306) 22:47:51,099 ERROR [stderr] (http--127.0.0.1-8080-1) at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190)
ãã®åŸãOppotunityService#createãåŒã³åºããæã«ããã§ã«ãã©ã³ã¶ã¯ã·ã§ã³ãããŒã«ããã¯ãšããŠããŒã¯ãããŠãããããããã§ã®ã¡ãœããåŒã³åºãã倱æããŸãã
22:47:51,274 ERROR [org.jboss.as.ejb3.tx.CMTTxInterceptor] (http--127.0.0.1-8080-1) javax.ejb.EJBTransactionRolledbackException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context) 22:47:51,275 ERROR [org.jboss.ejb3.invocation] (http--127.0.0.1-8080-1) JBAS014134: EJB Invocation failed on component OpportunityService for method public void javaee6.web.service.ServiceSupport.create(java.lang.Object): javax.ejb.EJBTransactionRolledbackException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context) at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:139) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:204) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:306) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final] at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
ã¡ãªã¿ã«ã念ã®ãã
// saveQuoteã¡ãœããã®å®è£ 次第ã§ãããŒã«ããã¯ãããã©ããã決ãŸã def unsafeOpportunityAndQuote(opp: Opportunity, qte: Quote): Unit = { try { saveQuote(qte) } catch { case e:Exception => println(s"Exception Cause[$e]") e.printStackTrace } //saveOpportunity(opp) }
ãšããããã«ãOpportunityService#createã®åŒã³åºããã³ã¡ã³ãã¢ãŠãããŠãããã¯ãããŒã«ããã¯ããŸãããã®å Žåã¯ããã¡ãµãŒããšãªã£ãŠããTransactionService#unsafeOppotunityAndQuoteãäŸå€ã§æããªããŠãããŒã«ããã¯ããããã§ãã
ãã¡ãã®åãã¯ããªããšãªãæã£ãŠããéãã§ããããŸããæåã®ãã¿ãŒã³ãããŒã«ããã¯ãããªãã£ãæç¹ã§ãäºæ³ãã€ããŸããâŠã
ãšããããã§ãEJBã®ã€ã³ã¹ã¿ã³ã¹ã«å¯ŸããŠã¡ãœããåŒã³åºããè¡ãããšã§ãEJBã®ãããã·è¶ãã«ã¢ã¯ã»ã¹ããå Žåã«ãã©ã³ã¶ã¯ã·ã§ã³ãéå§ãããïŒã€ã³ã¿ãŒã»ãããããïŒãšããç解ã§ãå°ãªããšãEJB Liteã®å Žåã¯ããããã§ããEJBå ã®ã¡ãœãããããèªã¯ã©ã¹ã®ã¡ãœãããåŒã³åºãå Žåã¯ããããã·ã§ã¯ãªãå®ã€ã³ã¹ã¿ã³ã¹ã觊ã£ãŠãããšããããšã§ããã
EJBããªã¢ãŒãåŒã³åºãããå Žåã¯ããŸãäºæ ãå€ããã®ãããããŸããããä»åã¯å¯Ÿè±¡å€ãšããŸããJava EE 7ã«ãªã£ãããEJB觊ããã©ããããããªããâŠã
ãšã¯ãããå®éã«è©ŠããŠã¿ããšãã£ã±ãå匷ã«ãªããŸããã