Migrate HAR hibernate archive to JBoss 7 - java

I'm migrating an application packaged as a HAR hibernate archive from JBoss AS5 to AS7. I have a number of questions, and I know I have a number of hurdles I have to face in order to migrate my application successfully. I don't mind researching things on my own - but at this point I'm not quite sure what is possible, or the direction I should take and would appreciate any pointers or comments.
I know that JBoss AS7 does not support HAR hibernate archives - so I have to make some sort of changes in order to get this to work. My app requires hibernate3, which I include as a dependency. My HAR is structured like
HAR
|
|-com
| |-business classes
| |-*class files and *hbm.xml files
|
|-META-INF
|-hibernate.xml
My hibernate.xml file looks like
<hibernate-configuration xmlns="urn:jboss:hibernate-deployer:1.0">
<session-factory name="java:/hibernate/SessionFactory" bean="jboss.har:service=Hibernate">
<property name="datasourceName">java:/MySqlDS</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- <property name="sessionFactoryInterceptor">org.jboss.test.hibernate.SimpleInterceptor</property> -->
<!-- <property name="hbm2ddlAuto">create</property> -->
<depends>jboss:service=Naming</depends>
<depends>jboss:service=TransactionManager</depends>
</session-factory>
</hibernate-configuration>
We are using *hbm.xml files in our HAR to define entities, and not the newer style of hibernate annotations. A couple of questions I have are:
-is there a way I can just package my HAR as a JAR and use it inside of AS7 without having to go through the trouble of rewrite my business classes to use annotations to define entities instead of using *hbm.xml files?
-if not is there a guide somewhere about converting your code to use hibernate annotations and persistence.xml? I don't mind doing research but right now I'm not sure what I should be researching.

HAR archives do not exist in JBoss 7 anymore. In fact even the ServiceMBeanSupport does not exist anymore. One possibility is to use some mechanism to create the SessionFactory and inject it into the JNDI. Another possibility is to “use and not use” the new JPA api. By “use” I mean define Hibernate configuration in a persistence.xml file and use the mapping detection feature available. This would allow the plain renaming of the .har to a .jar with an added META-INF/persistence.xml file without the need to hardcode all the mappings and classes in a long list somewhere. By “not use” I mean to have the JPA initialized but use the old SessionFactory instead because there is no reason to change to the new API when the old one works quite well.
However, another problem is that JBoss 7 is bundled with Hibernate 4 and the migration might not be straightforward. However there is still a possibility to bundle a Hibernate as lower as 3.5 in your application. Here is the persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="X">
<description>X</description>
<jta-data-source>java:/XOracleDS</jta-data-source>
<properties>
<!-- This tells JBoss to use Hibernate 3 (as low as 3.5) bundled into the application -->
<property name="jboss.as.jpa.providerModule" value="hibernate3-bundled" />
<!--<property name="jboss.as.jpa.managed" value="false"/>-->
<!-- This will bind the session factory to JNDI as we require -->
<property name="hibernate.session_factory_name" value="java:/hibernate/XOracleSessionFactory"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<!-- This is one of the trickiest parts as Hibernate 3.5 does not has a RegionFactory and we must use the one from ehcache to bridge the gap -->
<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory"/>
<!-- very important to allow same names as in JBoss 4 -->
<property name="hibernate.cache.region_prefix" value=""/>
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
<!-- This will make use of JBoss managed transactions. The factory is already present in JNDI -->
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
<property name="hibernate.jdbc.batch_size" value="20"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
</properties>
</persistence-unit>
</persistence>

Related

H2 database console: how to connect to an embedded H2 JPA database?

I have a couple of unit tests for an application's JPA layer. This JPA layer consists in JPA entities and a service providing the basic API required in order to persist the entities. The unit tets directly use the javax.persistence classes in order to handle the PersistenceManager. Then it tests the persistence API and I can see in the log the SQL statements to create tables and sequences, etc.
The relevant part of the persistence.xml file looks like:
<persistence-unit name="..." transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
...
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.format_sql" value="false"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
...
I have downloaded H2 1.4.200, the Windows installer, and I installed it on Windows 10. Now using the H2 console I want to connect to the database and inspect the tables, sequences, etc. that were created automatically by Hibernate.
So, going to http://localhost:8082 I get the following:
But when I try to connect to my database, using the defined JDBC connection string, I get the following:
What am I doing wrong here ?
Many thanks in advance.
Nicolas
Finally, I've replaced H2 with Oracle.

Annotation not created when generating Hibernate mapping files

I am following this link to generate hibernate file
https://www.mkyong.com/hibernate/how-to-generate-code-with-hibernate-tools/
the files are generated but without annotation.
I checked the "generate EJB3 annotation " but still it is not working
the DB is Postgres.
I use to do it the same way and it was working fine..
few weeks ago I upgrade to eclipse to oxygen and change my workplace
since then it is not working..
does any body know if there is a log file for the activity ? maybe I can find some thing there ?
this is my hibernate.cfg.xml file
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.url">jdbc:postgresql://xxxxx/yyy</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<!-- <property name="hibernate.enable_lazy_load_no_trans">false</property> -->
<property name="hibernate.search.autoregister_listeners">true</property>
<property name="hibernate.validator.apply_to_ddl">false</property>
<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
<property name="hibernate.enable_lazy_load_no_trans">true</property>
</session-factory>
After spending two days on it , I found the problem..
my hibernate version is 5.3 and still after changing the hibernate version to 5.2 (in the hibernate configuration window ) - it worked !!
After changing different possibilities in the configuration and connection, I changed the hibernate version from 5.3 to 5.2 and it works now ! (Tested on Photon and Oxygen versions of Eclipse)
In my case I have to check the checkboxe "Generate EJB3 annotations" with hibernate version 5.2 to make it work fine !

How turn off eclipselink sql statement logging in persistence.xml?

I've configured EclipseLink as JPA provider for my Spring application. The only problem is, it spams the console with SQL statements.
This is my persistence.xml configuration:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="jpa-persistence" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
<property name="eclipselink.logging.level" value="INFO"/>
<property name="logging.level" value="INFO"/>
</properties>
</persistence-unit>
</persistence>
I've found references to both eclipselink.logging.level and logging.level properties in internet, but none of them seems to work. I'm using slf4j, but I don't think it's relevant because I don't need to route SQL output through slf4j, I just want to get rid of it.
How should I configure my persistence.xml to stop SQL statement logging?
The version of EclipseLink I'm using:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.6.4</version>
</dependency>
This is how I instantiate JPA in my Spring application:
<!-- Define EclipseLink JPA Vendor Adapter -->
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="databasePlatform"
value="org.eclipse.persistence.platform.database.MySQLPlatform" />
<property name="generateDdl" value="true" />
<property name="showSql" value="false" />
</bean>
<!-- Entity Manager Factory -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="jpa-persistence"></property>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
</bean>
It is a EclipseLink specific behavior (reference).
EclipseLink states :
By default the log output goes to System.out or your console.
To configure the output to be logged to file the persistence unit
property eclipselink.logging.file can be set:
<property name="eclipselink.logging.file" value="output.log"/>
EclipseLink's logging service is plug-able and several different
logging integrations are supported including java.util.logging. To
enable java.util.logging the persistence unit property
eclipselink.logging.logger can be set:
To summarize, you have two solutions:
defining eclipselink.logging.file to avoid polluting the console.
This is quick hack but personally, I don't use this solution because it creates multiple log files and it makes harder readability of application logs.
defining eclipselink.logging.logger. It is the most flexible solution.
With EclipseLink 2.5+ , eclipselink.logging.loger can specify :
Custom logger
Fully qualified class name of a custom logger which implements
org.eclipse.persistence.logging.SessionLog
With this solution you could log through SLF4J and you could also customize the logs in a finer way.
Here is an example from GIT :
JavaLogger
Uses java.util.logging
java.util.logging, the API to avoid...
ServerLogger
Integrates with the application server's logging
DefaultLogger
(Default) Uses EclipseLink's native logger, DefaultSessionLog

property tags in persistence.xml when using JPA

I am new to JPA and use Hibernate as the JPA provider. I came to know that we need META-INF/persistence.xml configuration file.
I successfully created a simple Java program to persist data in DB using JPA.
All fine, doubts started when I looked into the persistence.xml file to understand it better.
Sample below:
<persistence-unit name="test-jpa" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url" value="jdbc:h2:tcp://localhost/~/test"/>
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
The following is the Java code for reading the configuration:
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("test-jpa");
The following are the doubts:
How do we know that Hibernate is the JPA provider? Is it inferred by seeing the property tags in the file?
In config file, there are many <property> tags, are they pre-defined which can appear in the file (for a given JPA provider) or can we randomly add any property? who reads those <property> tags?
A JPA provider would provide documentation that would tell you all of that. Doesn't yours? I'd be surprised.
You should either have a <provider> element in the persistence-unit to define which provider to use, or it would use the default for the environment that you are running in (in JavaSE you would need to have 1 and only one JPA provider in the CLASSPATH, in JavaEE the server would have its own default).
They are provider-specific. Any properties that are prefixed javax.persistence would be JPA STANDARD. The first 4 of those posted have javax.persistence variants that you should have used instead.

Java - Can Hibernate choose between two database configurations in persistence.xml?

I have a Java app running on Tomcat 7.0 with Hibernate managing the database.
I need to be able to switch the jdbc.url depending on a system environment variable (or possible another flag of sorts). Ultimately, I would like to be able to deploy a staging and production version of my webapp pointing to two different databases. However, at the moment, I have to physically change the jdbc.url value in persistence.xml and re-save it when switching between configurations.
My current persistence.xml file is:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="my_pu" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<shared-cache-mode>ALL</shared-cache-mode>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://my.rds.url.goes.here/mydatabase" />
<property name="javax.persistence.jdbc.user" value="myusername" />
<property name="javax.persistence.jdbc.password" value="mypassword" />
<property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
</properties>
</persistence-unit>
</persistence>
I've read about using createEntityManagerFactory() as an option, but I can't find any clean examples of how to implement this. I'm certain this issue has been dealt with before, but I can't find a clean tutorial or advice.
How can I have my Hibernate switch database configurations without having to rewrite the persistence.xml file each time?
A couple of ways to do it, if you use spring or maven in your project, could be:
With maven as your build tool, you can replace properties during build time based on a maven profile - through filtering in the maven resource plugin
If you use spring in your project the PropertyPlaceholderConfigurer can inject the values for you. It can read the values as jvm parameters or from property files. These property files may be put in the tomcat/conf directory so each tomcat knows its own configuration, or you may build all possible properties, select them based on spring profile

Categories