1 Reply Latest reply on Jan 15, 2008 7:44 PM by Martin

    Trivial Hibernate example with EJB3 and Hibernate, but trans

    Martin Newbie

      Hello folks,

      I'm trying to create a trivial example of a transaction working correctly with MySQ L5.0.x and local-tx-datasource and Connector/J 3.x. I'm using Hibernate and EJB3, and JBoss 4.0.x. I cannot get transactions to rollback w/ SessionContext.setRollbackOnly() OR by throwing an uncaught EJB/Runtime exception.

      Rolling back via the mysql command line client works great, and the tables in question are InnoDB.

      Here is my documentation of the problem -- I'd love it if anyone can tell me anything that looks weird. Please help -- this is so trivial it SHOULD work!

      mysql-ds.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <datasources>
       <local-tx-datasource>
       <jndi-name>MySqlDS</jndi-name>
       <connection-url>jdbc:mysql://127.0.0.1:3306/scheduler_db</connection-url>
       <driver-class>com.mysql.jdbc.Driver</driver-class>
       <user-name>censored</user-name>
       <password>censored</password>
       <metadata>
       <type-mapping>mySQL</type-mapping>
       </metadata>
       </local-tx-datasource>
      </datasources>
      


      persistence.xml:
      <persistence>
       <persistence-unit name="persistence-unit">
       <jta-data-source>java:/MySqlDS</jta-data-source>
       <properties>
       <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
       <property name="hibernate.connection.release_mode" value="auto"/>
       <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
       </properties>
       </persistence-unit>
      </persistence>
      


      My EJB3 session bean:
      @Stateless
      public class TestBean implements TestBeanLocal, TestBeanRemote
      {
      
       @PersistenceContext(name = "persistence-unit")
       EntityManager em;
      
       @Resource
       SessionContext ctx;
      
       public static final String RemoteJNDIName = "example/" + TestBean.class.getSimpleName() + "/remote";
       public static final String LocalJNDIName = "example/" + TestBean.class.getSimpleName() + "/local";
      
       @TransactionAttribute(TransactionAttributeType.REQUIRED)
       public void test()
       {
       Book book = new Book(null, "My first book", "Person 1");
       em.persist(book);
      
       Book book2 = new Book(null, "My second book", "Person 2");
       em.persist(book2);
      
       System.out.println("CURRENT TRANSACTION STATUS 1: " + (ctx.getRollbackOnly() ? "ROLLBACK" : "NOT ROLLBACK"));
       ctx.setRollbackOnly();
       System.out.println("CURRENT TRANSACTION STATUS 2: " + (ctx.getRollbackOnly() ? "ROLLBACK" : "NOT ROLLBACK"));
      
       Book book3 = new Book(null, "My third book", "Person 3");
       em.persist(book3);
      
       List someBooks = em.createQuery("from Book").getResultList();
      
       for (Iterator iter = someBooks.iterator(); iter.hasNext();)
       {
       Book element = (Book) iter.next();
       em.remove(element);
       }
       }
      


      My test client:
       public static void main(String[] args) throws Exception
       {
       Properties properties = new Properties();
       properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
       properties.put("java.naming.factory.url.pkgs", "=org.jboss.naming:org.jnp.interfaces");
       properties.put("java.naming.provider.url", "localhost:1099");
       Context context = new InitialContext(properties);
      
       TestBeanRemote beanRemote = (TestBeanRemote) context.lookup(TestBean.RemoteJNDIName);
       beanRemote.test();
       }
      


      Output log from JBoss:
      2008-01-10 17:15:40,755 DEBUG [org.jboss.remoting.transport.socket.ServerThread] WAKEUP in SERVER THREAD
      2008-01-10 17:15:40,991 DEBUG [org.jboss.remoting.transport.socket.ServerThread] beginning dorun
      2008-01-10 17:15:41,211 DEBUG [org.hibernate.impl.SessionImpl] opened session at timestamp: 4915213685571584
      2008-01-10 17:15:41,211 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Looking for a JTA transaction to join
      2008-01-10 17:15:41,211 DEBUG [org.hibernate.jdbc.JDBCContext] successfully registered Synchronization
      2008-01-10 17:15:41,211 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Looking for a JTA transaction to join
      2008-01-10 17:15:41,211 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Transaction already joined
      2008-01-10 17:15:41,220 DEBUG [org.hibernate.event.def.AbstractSaveEventListener] executing identity-insert immediately
      2008-01-10 17:15:41,224 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
      2008-01-10 17:15:41,224 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
      2008-01-10 17:15:41,352 DEBUG [org.hibernate.SQL] insert into book (title, author) values (?, ?)
      2008-01-10 17:15:41,420 DEBUG [org.hibernate.id.IdentifierGeneratorFactory] Natively generated identity: 1
      2008-01-10 17:15:41,420 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
      2008-01-10 17:15:41,420 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
      2008-01-10 17:15:41,420 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
      2008-01-10 17:15:41,420 DEBUG [org.hibernate.event.def.AbstractSaveEventListener] executing identity-insert immediately
      2008-01-10 17:15:41,421 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
      2008-01-10 17:15:41,421 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
      2008-01-10 17:15:41,421 DEBUG [org.hibernate.SQL] insert into book (title, author) values (?, ?)
      2008-01-10 17:15:41,421 DEBUG [org.hibernate.id.IdentifierGeneratorFactory] Natively generated identity: 2
      2008-01-10 17:15:41,421 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
      2008-01-10 17:15:41,421 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
      2008-01-10 17:15:41,421 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
      2008-01-10 17:15:41,421 INFO [STDOUT] CURRENT TRANSACTION STATUS 1: NOT ROLLBACK
      2008-01-10 17:15:41,422 INFO [STDOUT] CURRENT TRANSACTION STATUS 2: ROLLBACK
      2008-01-10 17:15:41,422 DEBUG [org.jboss.ejb3.entity.ManagedEntityManagerFactory] ************** closing entity managersession **************
      2008-01-10 17:15:41,447 DEBUG [org.jboss.remoting.transport.socket.ServerThread] begin thread wait
      


      Book.java (the hibernate entity):
      @Entity
      @Table(name = "book")
      @SequenceGenerator(name = "book_sequence", sequenceName = "book_id_seq")
      public class Book implements Serializable
      {
       /**
       *
       */
       private static final long serialVersionUID = -9108127436362270765L;
       private Integer id;
       private String title;
       private String author;
      
       public Book()
       {
       super();
       }
      
       public Book(Integer id, String title, String author)
       {
       super();
       this.id = id;
       this.title = title;
       this.author = author;
       }
      
       @Override
       public String toString()
       {
      
       return "Book: " + getId() + " Title " + getTitle() + " Author " + getAuthor();
       }
      
       /**
       * @return the author
       */
       public String getAuthor()
       {
       return author;
       }
      
       /**
       * @param author the author to set
       */
       public void setAuthor(String author)
       {
       this.author = author;
       }
      
       /**
       * @return the id
       */
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO, generator = "book_sequence")
       public Integer getId()
       {
       return id;
       }
      
       /**
       * @param id the id to set
       */
       public void setId(Integer id)
       {
       this.id = id;
       }
      
       /**
       * @return the title
       */
       public String getTitle()
       {
       return title;
       }
      
       /**
       * @param title the title to set
       */
       public void setTitle(String title)
       {
       this.title = title;
       }
      
      }