Create JPA EntityManager without persistence.xml configuration file

Is there a way to initialize an EntityManager without a duration unit? Can you provide all the necessary properties to create an object manager? I need to create an EntityManager from user-defined values ​​at runtime. Updating persistence.xml and recompiling is not an option.

Any idea on how to do this is more than welcome!

+63
jpa runtime entitymanager
Jan 01 '09 at 21:19
source share
5 answers

Is there a way to initialize an EntityManager without a specific save unit?

In the deployment descriptor persistence.xml you must define at least one persistence block.

Can you provide all the necessary properties to create an EntityManager ?

  • The name attribute is required. Other attributes and elements are optional. (JPA specification). Thus, it should be a more or less minimal persistence.xml file:
 <persistence> <persistence-unit name="[REQUIRED_PERSISTENCE_UNIT_NAME_GOES_HERE]"> SOME_PROPERTIES </persistence-unit> </persistence> 

In Java EE environments, the jta-data-source and non-jta-data-source elements are used to specify the global JNDI name of the JTA and / or non-JTA non-jta-data-source to be used by the persistence provider.

So, if your target application server supports JTA (JBoss, Websphere, GlassFish), your persistence.xml looks like this:

 <persistence> <persistence-unit name="[REQUIRED_PERSISTENCE_UNIT_NAME_GOES_HERE]"> <!--GLOBAL_JNDI_GOES_HERE--> <jta-data-source>jdbc/myDS</jta-data-source> </persistence-unit> </persistence> 

If your target application server does not support JTA (Tomcat), your persistence.xml looks like this:

 <persistence> <persistence-unit name="[REQUIRED_PERSISTENCE_UNIT_NAME_GOES_HERE]"> <!--GLOBAL_JNDI_GOES_HERE--> <non-jta-data-source>jdbc/myDS</non-jta-data-source> </persistence-unit> </persistence> 

If your data source is not tied to a global JNDI (for example, outside a Java EE container), you usually define the properties of the provider, driver, URL, user and password of the JPA. But the name of the property depends on the JPA provider. So, for Hibernate as a JPA provider, your persistence.xml file will look like this:

 <persistence> <persistence-unit name="[REQUIRED_PERSISTENCE_UNIT_NAME_GOES_HERE]"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>br.com.persistence.SomeClass</class> <properties> <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/> <property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/EmpServDB;create=true"/> <property name="hibernate.connection.username" value="APP"/> <property name="hibernate.connection.password" value="APP"/> </properties> </persistence-unit> </persistence> 

Transaction Type Attribute

In general, in Java EE environments, the transaction type RESOURCE_LOCAL assumes that a non-JTA data source will be provided. In Java EE, if this item is not specified, JTA is used by default. In Java SE, if this item is not specified, the default value RESOURCE_LOCAL may be accepted.

  • To ensure portability of a Java SE application , you must explicitly specify the managed persistence classes that are included in the persistence block (JPA specification)

I need to create an EntityManager from user defined values ​​at runtime

So use this:

 Map addedOrOverridenProperties = new HashMap(); // Let suppose we are using Hibernate as JPA provider addedOrOverridenProperties.put("hibernate.show_sql", true); Persistence.createEntityManagerFactory(<PERSISTENCE_UNIT_NAME_GOES_HERE>, addedOrOverridenProperties); 
+53
Jan 02 '09 at 7:51
source share

Yes, you can without using any xml file using spring, like this, inside the @Configuration class (or its equivalent spring config xml):

 @Bean public LocalContainerEntityManagerFactoryBean emf(){ properties.put("javax.persistence.jdbc.driver", dbDriverClassName); properties.put("javax.persistence.jdbc.url", dbConnectionURL); properties.put("javax.persistence.jdbc.user", dbUser); //if needed LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); emf.setPersistenceProviderClass(org.eclipse.persistence.jpa.PersistenceProvider.class); //If your using eclipse or change it to whatever you're using emf.setPackagesToScan("com.yourpkg"); //The packages to search for Entities, line required to avoid looking into the persistence.xml emf.setPersistenceUnitName(SysConstants.SysConfigPU); emf.setJpaPropertyMap(properties); emf.setLoadTimeWeaver(new ReflectiveLoadTimeWeaver()); //required unless you know what your doing return emf; } 
+21
Aug 26 '12 at 1:15
source share

I managed to create an EntityManager with Hibernate and PostgreSQL using only Java code (with Spring configuration):

 @Bean public DataSource dataSource() { final PGSimpleDataSource dataSource = new PGSimpleDataSource(); dataSource.setDatabaseName( "mytestdb" ); dataSource.setUser( "myuser" ); dataSource.setPassword("mypass"); return dataSource; } @Bean public Properties hibernateProperties(){ final Properties properties = new Properties(); properties.put( "hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect" ); properties.put( "hibernate.connection.driver_class", "org.postgresql.Driver" ); properties.put( "hibernate.hbm2ddl.auto", "create-drop" ); return properties; } @Bean public EntityManagerFactory entityManagerFactory( DataSource dataSource, Properties hibernateProperties ){ final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource( dataSource ); em.setPackagesToScan( "net.initech.domain" ); em.setJpaVendorAdapter( new HibernateJpaVendorAdapter() ); em.setJpaProperties( hibernateProperties ); em.setPersistenceUnitName( "mytestdomain" ); em.setPersistenceProviderClass(HibernatePersistenceProvider.class); em.afterPropertiesSet(); return em.getObject(); } 

The call to LocalContainerEntityManagerFactoryBean.afterPropertiesSet() significant , because otherwise the factory will never be created, and then getObject() will return null and you will chase after NullPointerException all day. >: - (

Then he worked with the following code:

 PageEntry pe = new PageEntry(); pe.setLinkName( "Google" ); pe.setLinkDestination( new URL( "http://www.google.com" ) ); EntityTransaction entTrans = entityManager.getTransaction(); entTrans.begin(); entityManager.persist( pe ); entTrans.commit(); 

Where is my essence:

 @Entity @Table(name = "page_entries") public class PageEntry { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; private String linkName; private URL linkDestination; // gets & setters omitted } 
+11
Nov 08 '14 at 6:51
source share

Here's a solution without Spring. Constants taken from org.hibernate.cfg.AvailableSettings :

 entityManagerFactory = new HibernatePersistenceProvider().createContainerEntityManagerFactory( archiverPersistenceUnitInfo(), ImmutableMap.<String, Object>builder() .put(JPA_JDBC_DRIVER, JDBC_DRIVER) .put(JPA_JDBC_URL, JDBC_URL) .put(DIALECT, Oracle12cDialect.class) .put(HBM2DDL_AUTO, CREATE) .put(SHOW_SQL, false) .put(QUERY_STARTUP_CHECKING, false) .put(GENERATE_STATISTICS, false) .put(USE_REFLECTION_OPTIMIZER, false) .put(USE_SECOND_LEVEL_CACHE, false) .put(USE_QUERY_CACHE, false) .put(USE_STRUCTURED_CACHE, false) .put(STATEMENT_BATCH_SIZE, 20) .build()); entityManager = entityManagerFactory.createEntityManager(); 

And the notorious PersistenceUnitInfo

 private static PersistenceUnitInfo archiverPersistenceUnitInfo() { return new PersistenceUnitInfo() { @Override public String getPersistenceUnitName() { return "ApplicationPersistenceUnit"; } @Override public String getPersistenceProviderClassName() { return "org.hibernate.jpa.HibernatePersistenceProvider"; } @Override public PersistenceUnitTransactionType getTransactionType() { return PersistenceUnitTransactionType.RESOURCE_LOCAL; } @Override public DataSource getJtaDataSource() { return null; } @Override public DataSource getNonJtaDataSource() { return null; } @Override public List<String> getMappingFileNames() { return Collections.emptyList(); } @Override public List<URL> getJarFileUrls() { try { return Collections.list(this.getClass() .getClassLoader() .getResources("")); } catch (IOException e) { throw new UncheckedIOException(e); } } @Override public URL getPersistenceUnitRootUrl() { return null; } @Override public List<String> getManagedClassNames() { return Collections.emptyList(); } @Override public boolean excludeUnlistedClasses() { return false; } @Override public SharedCacheMode getSharedCacheMode() { return null; } @Override public ValidationMode getValidationMode() { return null; } @Override public Properties getProperties() { return new Properties(); } @Override public String getPersistenceXMLSchemaVersion() { return null; } @Override public ClassLoader getClassLoader() { return null; } @Override public void addTransformer(ClassTransformer transformer) { } @Override public ClassLoader getNewTempClassLoader() { return null; } }; } 
+9
Feb 21 '17 at 16:22
source share

When using a simple JPA, if you have a PersistenceProvider implementation (e.g. Hibernate), you can use PersistenceProvider # createContainerEntityManagerFactory (PersistenceUnitInfo information, map map) to load EntityManagerFactory without the need for << 22>.

However, it is annoying that you need to implement the PersistenceUnitInfo interface, so you better use Spring or Hibernate, which support JPA loading without the persistence.xml file:

 this.nativeEntityManagerFactory = provider.createContainerEntityManagerFactory( this.persistenceUnitInfo, getJpaPropertyMap() ); 

Where PersistenceUnitInfo is implemented by Spring-specific MutablePersistenceUnitInfo .

Give up this article for a good demonstration of how you can achieve this with Hibernate.

+3
Sep 20 '16 at 13:18
source share



All Articles