Working with CMT EJB3 and Mybatis

949 views
Skip to first unread message

Tyrion

unread,
Oct 31, 2011, 12:11:03 PM10/31/11
to mybatis-user
Hi,
I have a problem with context managed transactions, I'm triying to
work with EJB3 and CMT and Mybatis in a GlassFish3 server
I'm using this configuration file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">

<transactionManager type="EXTERNAL">
<property name="SetAutoCommitAllowed" value="false" />
</transactionManager>

<dataSource type="JNDI">
<property name="data_source" value="jdbc/mytest" />
</dataSource>

</environment>
</environments>
<mappers>
<mapper resource="mybatis/Mapper.xml" />
</mappers>
</configuration>

But when I try to get a session a exception is raised..

[#|2011-10-31T12:39:46.393-0300|SEVERE|glassfish3.1.1|
javax.enterprise.system.std.com.sun.enterprise.server.logging|
_ThreadID=25;_ThreadName=http-thread-pool-8080(2);|
org.apache.ibatis.exceptions.PersistenceException:
### Error building SqlSession.
### The error may exist in SQL Mapper Configuration
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing
SQL Mapper Configuration. Cause:
org.apache.ibatis.builder.BuilderException: Error resolving class .
Cause: org.apache.ibatis.type.TypeException: Could not resolve type
alias 'EXTERNAL'. Cause: java.lang.ClassNotFoundException: Cannot
find class: EXTERNAL
at
org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:
8)
at
org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:
32)

I have a static class who give the session

import java.io.IOException;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class ConnectionFactory {
private static SqlSessionFactory sqlMapper;
static{
try{
sqlMapper = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis/
Configuration.xml"));
}catch(Exception e){
//TODO correct this
e.printStackTrace();
}
}

public static SqlSession getSession() throws IOException{
return sqlMapper.openSession();
}
}

and I tried to get the session from a servlet, inside the ejb, in a
class inside a jar.. but not worked in any way...

with <transactionManager type="JDBC"/> I dont have problems

Any Idea???

Thanks in advance






Chema

unread,
Oct 31, 2011, 12:33:01 PM10/31/11
to mybati...@googlegroups.com
Maybe it must be "MANAGED" instead of "EXTERNAL" 
Read myBatis 3.x manual, not iBatis 2.x

Regards

2011/10/31 Tyrion <tyrio...@gmail.com>

Tyrion

unread,
Oct 31, 2011, 3:01:34 PM10/31/11
to mybatis-user
Thanks

With "Managed" Worked!!!...

but I'm studing with

http://code.google.com/p/mybatis/downloads/detail?name=MyBatis-3-User-Guide.pdf

In the page 51, the guide is wrong

<environment id="production">
<transactionManager type="EXTERNAL">
...
<dataSource type="JNDI">
...
</environment>

But, now, with your guidance, I noted the page 19

<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>

Thank you very much..

Just a last Question ....

The guide says this:

MANAGED – This configuration simply does almost nothing. It never
commits, or rolls back a connection. Instead, it lets the container
manage the full lifecycle of the transaction (e.g. Spring or a JEE
Application Server context).
By default it does close the connection. However, some containers
don’t expect this, and thus if you need to stop it from closing the
connection, set the closeConnection property to false.
For example:

<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>

The question is... "close the connection" is the same
session.close() ?
The container will close my session and the session will return to the
pool when the container made commit o rollback?
and if I prefer maintein opened my session I can use the property...

<property name="closeConnection" value="false"/>

Thanks again...














On 31 oct, 13:33, Chema <demablo...@gmail.com> wrote:
> Maybe it must be "MANAGED" instead of "EXTERNAL"
> Read myBatis 3.x manual, not iBatis 2.x
>
> Regards
>
> 2011/10/31 Tyrion <tyrion....@gmail.com>

Chema

unread,
Oct 31, 2011, 3:39:54 PM10/31/11
to mybati...@googlegroups.com

The question is... "close the connection" is the same
session.close() ?

I guess it does.
 
The container will close my session and the session will return to the
pool when the container made commit o rollback?
and if I prefer maintein opened my session I can use the property...

<property name="closeConnection" value="false"/>

Thanks again...

The documentation is not clear.
I think this property is important when you use a JNDI datasource pool , because close() operation is managed by external agent , like an application server.
I this case, application server could try close an already closed connection and throws an error.

So, I guess I could set a JDBC transaction manager and a JNDI external pool , and I think , in this case, it's important can set "closeConnection" property to false.
But I don't know it


MyBatis devs can solve me this doubt 

Regards

Jeff Butler

unread,
Nov 1, 2011, 9:57:33 AM11/1/11
to mybati...@googlegroups.com
The documentation is wrong when it mentions EXTERNAL transaction
manager - it should be MANAGED. I'll fix that.

The documentation mentions on page 19 that the MANAGED transaction
manager closes connections unless you explicitly tell it not to. This
is correct in most cases. The close happens when you do a
session.close().

Jeff Butler

Jeff Butler

unread,
Nov 1, 2011, 10:05:17 AM11/1/11
to mybati...@googlegroups.com
One more thing...on most application servers, connection.close() is
the correct operation with JNDI data sources - but this simply tells
the server that the connection is available for reuse. It does not
actually close the physical connection - that is still managed by the
app server. So you should NOT set the closeConnection property to
false unless you know for sure that you should do that.

Jeff Butler

Tyrion

unread,
Nov 2, 2011, 12:03:37 PM11/2/11
to mybatis-user
Hi...

now i have my configuration file with

<transactionManager type="MANAGED"/>

and I get the session with

sqlMapper = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis/
sqlMapConfig.xml"));
session=sqlMapper.openSession();

but....
for "Container-Managed Transactions"

I don't know how to connect the session of mybatis with the container

My EJB now is like that

import java.io.IOException;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagementType;
import org.apache.ibatis.session.SqlSession;

import com.utils.MyData;
import com.utils.MyDataMapper;
/**
* Session Bean implementation class BeanSinEstado
*/

@TransactionManagement(TransactionManagementType.CONTAINER) // Good
@Stateless
@LocalBean
public class BeanSinEstado {
//@PersistenceContext(unitName="??") <-- Maybe
//private EntityManager em; <-- ??
public BeanSinEstado() {}
@TransactionAttribute(TransactionAttributeType.REQUIRED) //
Good
public int numerito(SqlSession session,int num,int num2) throws
IOException{
// now I'm giving the session in the parameters list, but i
supose this is not correct with CMT
MyDataMapper mapper = session.getMapper(MyDataMapper.class);
MyData mit = new MyData();
mit.setId(num);
mit.setField("Hi world");
mapper.insertData(mit);
int id=1;
return id;
}
}

with google i can't find any example of this..

Any idea?

Thanks in Advance

Eduardo

unread,
Nov 2, 2011, 5:40:41 PM11/2/11
to mybatis-user
Hi Tyron,

You must open, use and commit your session inside the EJB
transactional method.

Note, that commit will not call connection.commit() but it will flush
batch statements in case you use them.

Tyrion

unread,
Nov 2, 2011, 7:43:15 PM11/2/11
to mybatis-user
Thanks, now Works!!

I created a endpoint bean with this

@WebService(endpointInterface = "com.myservice.web.sei.MiServiceWS")
@TransactionManagement(TransactionManagementType.CONTAINER)
@Stateless
@LocalBean
public class MyServiceBean implements MyServiceWS{

and created the session inside this bean

I tested the commit and rollback and works OK, in this bean and in
other bean giving the session as a parameter.

I tried without session.close and the pool was filled :(
I put the session.close and the pool don't have problems...

Thanks again..

Eduardo

unread,
Nov 3, 2011, 3:12:12 AM11/3/11
to mybatis-user
Ah, yes, I meant open, use, commit and close it. Otherwise jdbc
connections will not be returned to the pool. But already discovered
that :)

Joe

unread,
Jul 9, 2013, 9:26:44 PM7/9/13
to mybati...@googlegroups.com
Hi Eduardo,

I am going to use EJB3.1 to manage the transaction of mybatis.
Can you please show me an example? and what do you mean open, use, commit, and close it in EJB?
what else if I need to rollback manually in EJB due to my business logic?

Thanks.

Guy Rouillier

unread,
Jul 10, 2013, 5:07:11 PM7/10/13
to mybati...@googlegroups.com
On 7/9/2013 9:26 PM, Joe wrote:
> Hi Eduardo,
>
> I am going to use EJB3.1 to manage the transaction of mybatis.
> Can you please show me an example? and what do you mean open, use,
> commit, and close it in EJB?
> what else if I need to rollback manually in EJB due to my business logic?

See the MyBatis User's Guide, section 3.1.7 environments, If you are
working within the EJB environment, then you should be using

<transactionManager type="MANAGED">

As you know, in such an environment, you should not be doing your own
commits and rollbacks. The container takes care of that for you.

--
Guy Rouillier
Reply all
Reply to author
Forward
0 new messages