title: Issues With JNDI in Hibernate Persistence
body: <p>I am learning the book "Java Persistence with Hibernate 2nd edition". I am trying to run the source code the book has provided but getting Exceptions. The problem is in the JNDI.</p>
  
  <p>These are the codes and the exceptions:</p>
  
  <pre><code>public enum DatabaseProduct {
  
   // additional code here
  
      MYSQL(
          new DataSourceConfiguration() {
              @Override
              public void configure(PoolingDataSource ds, String connectionURL) {
                  // TODO: MySQL XA support is completely broken, we use the BTM XA wrapper
                  //ds.setClassName("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");
                  ds.setClassName("bitronix.tm.resource.jdbc.lrc.LrcXADataSource");
                  ds.getDriverProperties().put(
                      "url",
                      connectionURL != null
                          ? connectionURL :
                          "jdbc:mysql://localhost/hibernate?sessionVariables=sql_mode='PIPES_AS_CONCAT'"
  
                  );
  
                  ds.getDriverProperties().put("driverClassName", "com.mysql.jdbc.Driver");
              }
          },
          // Yes, this should work with 5.6, no idea why Gail named it 5.7
          org.hibernate.dialect.MySQL57InnoDBDialect.class.getName()
      );
  
      public DataSourceConfiguration configuration;
      public String hibernateDialect;
  
      private DatabaseProduct(DataSourceConfiguration configuration,
                              String hibernateDialect) {
          this.configuration = configuration;
          this.hibernateDialect = hibernateDialect;
      }
  
      public interface DataSourceConfiguration {
  
          void configure(PoolingDataSource ds, String connectionURL);
      }
  </code></pre>
  
  <p>Transaction Manager</p>
  
  <pre><code>public class TransactionManagerSetup {
  
      public static final String DATASOURCE_NAME = "myDS";
  
      private static final Logger logger =
          Logger.getLogger(TransactionManagerSetup.class.getName());
  
      protected final Context context = new InitialContext();
      protected final PoolingDataSource datasource;
      public final DatabaseProduct databaseProduct;
  
      public TransactionManagerSetup(DatabaseProduct databaseProduct) throws Exception {
          this(databaseProduct, null);
      }
  
      public TransactionManagerSetup(DatabaseProduct databaseProduct,
                                     String connectionURL) throws Exception {
  
          logger.fine("Starting database connection pool");
  
          logger.fine("Setting stable unique identifier for transaction recovery");
          TransactionManagerServices.getConfiguration().setServerId("myServer1234");
  
          logger.fine("Disabling JMX binding of manager in unit tests");
          TransactionManagerServices.getConfiguration().setDisableJmx(true);
  
          logger.fine("Disabling transaction logging for unit tests");
          TransactionManagerServices.getConfiguration().setJournal("null");
  
          logger.fine("Disabling warnings when the database isn't accessed in a transaction");
          TransactionManagerServices.getConfiguration().setWarnAboutZeroResourceTransaction(false);
  
          logger.fine("Creating connection pool");
          datasource = new PoolingDataSource();
          datasource.setUniqueName(DATASOURCE_NAME);
          datasource.setMinPoolSize(1);
          datasource.setMaxPoolSize(5);
          datasource.setPreparedStatementCacheSize(10);
  
          // Our locking/versioning tests assume READ COMMITTED transaction
          // isolation. This is not the default on MySQL InnoDB, so we set
          // it here explicitly.
          datasource.setIsolationLevel("READ_COMMITTED");
  
          // Hibernate's SQL schema generator calls connection.setAutoCommit(true)
          // and we use auto-commit mode when the EntityManager is in suspended
          // mode and not joined with a transaction.
          datasource.setAllowLocalTransactions(true);
  
          logger.info("Setting up database connection: " + databaseProduct);
          this.databaseProduct = databaseProduct;
          databaseProduct.configuration.configure(datasource, connectionURL);
  
          logger.fine("Initializing transaction and resource management");
          datasource.init();
      }
  
      public Context getNamingContext() {
          return context;
      }
  
      public UserTransaction getUserTransaction() {
          try {
              return (UserTransaction) getNamingContext()
                  .lookup("java:comp/UserTransaction");
          } catch (Exception ex) {
              throw new RuntimeException(ex);
          }
      }
  
      public DataSource getDataSource() {
          try {
              return (DataSource) getNamingContext().lookup(DATASOURCE_NAME);
          } catch (Exception ex) {
              throw new RuntimeException(ex);
          }
      }
  
      public void rollback() {
          UserTransaction tx = getUserTransaction();
          try {
              if (tx.getStatus() == Status.STATUS_ACTIVE ||
                  tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
                  tx.rollback();
          } catch (Exception ex) {
              System.err.println("Rollback of transaction failed, trace follows!");
              ex.printStackTrace(System.err);
          }
      }
  
      public void stop() throws Exception {
          logger.fine("Stopping database connection pool");
          datasource.close();
          TransactionManagerServices.getTransactionManager().shutdown();
      }
  
  }
  </code></pre>
  
  <p>Message class</p>
  
  <pre><code>@Entity
  public class Message{
  
      @Id
      @GeneratedValue
      private Long id;
      private String text;
  
      public Message(){}
  
      public String getText(){
          return this.text;
      }    
      public void setText(String text) {
          this.text = text;
      }
  
  }
  </code></pre>
  
  <p>Main class</p>
  
  <pre><code>public class HelloWorldJPA {
  
      public static void main(String[] args){
          try {
              EntityManagerFactory emf = Persistence.createEntityManagerFactory("HelloWorldPU");
  
              TransactionManagerSetup TM = null;
              try {
                  TM = new TransactionManagerSetup(DatabaseProduct.MYSQL);
              } catch (Exception ex) {
                  Logger.getLogger(HelloWorldJPA.class.getName()).log(Level.SEVERE, null, ex);
              }
  
              UserTransaction tx = TM.getUserTransaction();
              try {
                  tx.begin();
              } catch (NotSupportedException | SystemException ex) {
                  Logger.getLogger(HelloWorldJPA.class.getName()).log(Level.SEVERE, null, ex);
              }
  
              EntityManager em = emf.createEntityManager();
  
              Message message = new Message();
              message.setText("Hello World!");
  
              em.persist(message);
  
              tx.commit();
  
              em.close();
          } catch (HeuristicMixedException | HeuristicRollbackException | IllegalStateException | RollbackException | SecurityException | SystemException ex) {
              Logger.getLogger(HelloWorldJPA.class.getName()).log(Level.SEVERE, null, ex);
          }
      }
  }
  </code></pre>
  
  <p>Persistence.xml</p>
  
  <pre><code>&lt;persistence
      version="2.1"
      xmlns="http://xmlns.jcp.org/xml/ns/persistence"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
      http://xmlns.jcp.org/xml/ns/persistence_2_1.xsd"&gt;
  
      &lt;persistence-unit name="HelloWorldPU"&gt;
          &lt;jta-data-source&gt;myDS&lt;/jta-data-source&gt;
          &lt;class&gt;com.mycompany.persistencewithhibernate.Message&lt;/class&gt;
          &lt;exclude-unlisted-classes&gt;true&lt;/exclude-unlisted-classes&gt;
          &lt;properties&gt;
  
              &lt;property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/&gt;
              &lt;property name="hibernate.format_sql" value="true"/&gt;
              &lt;property name="hibernate.use_sql_comments" value="true"/&gt;
  
  
  
  
          &lt;/properties&gt;
      &lt;/persistence-unit&gt;
  &lt;/persistence&gt;
  </code></pre>
  
  <p>Exceptions</p>
  
  <pre><code>Exception in thread "main" javax.persistence.PersistenceException: Unable to build entity manager factory
      at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:66)
      at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
      at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
      at com.mycompany.persistencewithhibernate.HelloWorldJPA.main(HelloWorldJPA.java:20)
  Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
      at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:244)
      at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:208)
      at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
      at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
      at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
      at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
      at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
      at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352)
      at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111)
      at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:770)
      at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:797)
      at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
      ... 3 more
  Caused by: org.hibernate.engine.jndi.JndiException: Error parsing JNDI name [myDS]
      at org.hibernate.engine.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:124)
      at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:95)
      at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:98)
      at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
      at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
      at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
      at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
      at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
      at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
      at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88)
      at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:234)
      ... 14 more
  Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
      at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
      at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
      at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:344)
      at javax.naming.InitialContext.getNameParser(InitialContext.java:499)
      at org.hibernate.engine.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:118)
      ... 24 more
  </code></pre>