/
JndiEM.scala
95 lines (84 loc) · 2.74 KB
/
JndiEM.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
* Copyright 2008-2016 Derek Chen-Becker
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
*/
package org.scala_libs.jpa
import javax.persistence._
import javax.naming.InitialContext
import javax.transaction.{Status,UserTransaction}
/**
* <p>This class represents an EntityManager factory that is retrieved from JNDI, using JTA
* to handle transactions. An example of usage would be:</p>
*
* <pre>
* object FooEM extends JndiEMF("java:/myEM")
*
* ...
*
* def doSomething = {
* val em = FooEM.newEM
* ...
* em.close()
* }
* </pre>
*
*
* @param jndiName The full JNDI binding for the managed EntityManager, such
* as "java:comp/env/persistence/myem".
*
* @author Derek Chen-Becker
*/
class JndiEMF(val jndiName : String) extends ScalaEMFactory {
/**
* Holds an InitialContext for use with JNDI.
*/
lazy val ctxt = new InitialContext()
/**
* Returns the current UserTransaction retrieved from JNDI.
*/
def tx = ctxt.lookup("java:comp/UserTransaction").asInstanceOf[UserTransaction]
private val txStatus = Map(Status.STATUS_ACTIVE -> "ACTIVE",
Status.STATUS_COMMITTED -> "COMMITTED",
Status.STATUS_COMMITTING -> "COMMITTING",
Status.STATUS_MARKED_ROLLBACK -> "MARKED_ROLLBACK",
Status.STATUS_NO_TRANSACTION -> "NO_TRANSACTION",
Status.STATUS_PREPARED -> "PREPARED",
Status.STATUS_PREPARING -> "PREPARING",
Status.STATUS_ROLLING_BACK -> "ROLLING_BACK",
Status.STATUS_ROLLEDBACK -> "ROLLEDBACK",
Status.STATUS_UNKNOWN -> "UNKNOWN")
/**
* Retrieves an EntityManager via JNDI and associates it with a JTA transaction.
*/
def openEM () = {
// JNDI EMs want an existing JTA transaction
tx.begin()
val em = ctxt.lookup(jndiName).asInstanceOf[EntityManager]
em
}
/**
* Commits the transaction if it hasn't been marked for rollback.
*/
def closeEM (em : EntityManager) = {
/* We only want to commit if we haven't already thrown an exception (due to a constraint violation, etc)
*/
if (tx.getStatus() == Status.STATUS_MARKED_ROLLBACK) {
tx.rollback()
} else if (tx.getStatus() == Status.STATUS_ACTIVE) {
tx.commit()
}
}
// Simply return the JNDI name as the Persistence Unit name
def getUnitName = jndiName
}