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
Related
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.
I am writing a javaEE application, using hibernate. The application will be running on multiple environments (dev, qa, prod etc.) & will have separate dbs's associated with each of them. I would like to set the hibernate properties like jdbc-url, username , password etc. separately for each of these environments.
My current persistence.xml looks like :
<persistence-unit name="PU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<validation-mode>CALLBACK</validation-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
<property name="hibernate.event.merge.entity_copy_observer" value="allow"/>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:#host/schema"/>
<property name="hibernate.connection.username" value="abc"/>
<property name="hibernate.connection.password" value="***"/>
</properties>
</persistence-unit>
I am using the persistence unit as follows in my java code:
#PersistenceContext(unitName = "PU")
private EntityManager em;
Is there a way that I can inject the hibernate properties, which are stored in separate properties files, into EntityManager for different environments ?
Please note that I am using JTA and hence cannot use EntityManagerFactory. Also I am not & do not want to use spring.
It is really a BAAAAAAD idea to include environment-specific information in your application WAR/EAR bundle (either by including multiple configs, or by creating different bundles for different environment). Different database, for example, should be maintained in the container.
In your case, your persistence.xml should look like:
<persistence>
<persistence-unit name="PU">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/fooAppDs</jta-data-source>
<properties>
... ...
</properties>
</persistence-unit>
</persistence>
and of course you should have corresponding resource-ref for jdbc/fooAppDs.
By doing so, you can deploy your application in any environment. You just need to create correct datasource in your container and assign it to jdbc/fooAppDs.
Another approach I believe will work, though I will not recommend, is by creating hibernate.cfg.xml in classpath. You may want to have a local file system location and add that in classpath, instead of putting the file in your JAR/WAR/EAR.
Since you do not want to use external library such as Spring to bootstrap your persistence units, why not use your build system to do this. If you are using maven, you can use mix of maven filtering and profiles to filter based on properties file or if you are using any other build tool, you can add a task (or equivalent) to copy file contents from different files to actual file depending upon some external system/environmental variable.
We used maintain property files for each environment such as DEV,QA,PROD,UAT etc in different files and copy one of them during build.
Ant build
<property environment="env" />
<!-- ***** COMMAND LINE ARGUMENTS DEMOED HERE -->
<property name="build_type" value= "${env.build_type}"/>
<copy todir="deploy">
<fileset dir="src_dir"/>
<globmapper from=${env.build_type}".persistence.xml" to="persistence.xml"/>
</copy>
Run build like this
ant -Denv.build_type=PROD
This will copy PROD.persistence.xml to persistence.xml
ant -Denv.build_type=DEV
This will copy DEV.persistence.xml to persistence.xml
With Spring Profile you could initiate entity manager beans depending upon the active profile that will refer to the persistence.xml like dev-persistence.xml, test-persisitence.xml, prod-persistence.xml of your environment. And you can set Active profile using web.xml. Mostly the web.xml won't change that much so you can keep the web.xml in your repository with the spring profile active property set for that enviornment.
you can configure your spring-config.xml file as following
MYSQL
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/kaya_db" />
<property name="username" value="root" />
<property name="password" value="nxtlife" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="packagesToScan" value="com.nxtlife.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory">
</bean>
2.Similar for other database like oracle,postgre with different name of datasource,sessionfactory and transactionmanager.
3. Finally you can get object of session factory using following sessionfactory name
#Modifier("sessionfactoryname")
#Autowired
private SessionFactory obj;
similar for different database
I am trying to configure a test for hibernate 4.3 with JPA and Spring 4 using the following config:
<bean id="em" class="LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="persistenceXmlLocation"
value="classpath:integrations/hibernate4/jpa/persistence.xml" />
</bean>
Now the persistence config looks as follows:
<persistence-unit name="test" >
<class>hibernate4.jpa.JpaEntity</class>
<class>hibernate4.jpa.JpaHiLoEntity</class>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
If I run the above with hibernate 4.2.4 everything runs fine, however with 4.3 the above setup loads ALL hbm.xml resource files, some of which refer to classes that are not present on the classpath, causing ClassNotFoundException.
Does anyone know what the reason for the changed behavior is and how to stop hibernate from scanning for hbm.xml files (packagesToScan property did not work either)?
I ran into this problem as well. The hibernate.archive.autodetection property controls what Hibernate will automatically scan for:
If the property is undefined, hbm files will be included, and annotated classes will be included unless <exclude-unlisted-classes> is set to true.
If the value of the property contains "hbm" then .hbm.xml files will be included. Otherwise they won't be.
If the value contains "class", then any annotated classes on the classpath will be included. Otherwise they won't be.
If the property is defined at all, regardless of its value, it affects the behavior of Hibernate. See the org.hibernate.jpa.boot.scan.internal.StandardScanOptions constructor.
For my purposes, I needed the persistence unit to include only the entities that were explicitly listed in <class> elements. To accomplish this, I defined the property with a value of "none":
<persistence-unit name="num2" transaction-type="RESOURCE_LOCAL">
...
<properties>
...
<property name="hibernate.archive.autodetection" value="none" />
</properties>
</persistence-unit>
Unfortunately, the only documentation I could find on this property was for the stable release, whatever that is. There was no mention of it in the docs for Hibernate 4.3, but that is the version I use and I can confirm the property works.
Also you can also configure the bean em without using the file persistence.xml. e.g.:
<bean id="em"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:packagesToScan="···.model">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:showSql="false"
p:databasePlatform="org.hibernate.dialect.SQLServerDialect" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
The exclude-unlisted-classes doesn't work if your class is in the packages to scan, e.g. you want to have it registered, but doesn't want the hbm.xml for it.
I fixed that using hibernate property hibernate.archive.autodetection set to class, making Hibernate scan only classes and not mapping files.
<properties>
<property name="hibernate.archive.autodetection" value="class" />
</properties
I have a java web application deployed on Jboss 6.1.0, that uses infinispan 5.2.6.Final.
I'm trying to set a per Entity specific expiration.lifespan following this guide
http://infinispan.org/docs/5.2.x/user_guide/user_guide.html#_advanced_configuration_2
for my Entity bean com.myenterprise.myproject.dal.ejb.entity.RefStatus.
The guide states the following:
You can also override eviction/expiration settings on a per entity/collection
type basis in such way that the overriden settings only afftect that particular
entity (i.e. com.acme.Person) or collection type (i.e. com.acme.Person.addresses).
For example:
<property name="hibernate.cache.infinispan.com.acme.Person.expiration.lifespan" value= "65000"/>
So, i've added the following element to my persistence.xml, to reduce the lifespan to 10 milliseconds for test purposes, in order to fine tune it later:
<property name="hibernate.cache.infinispan.com.myenterprise.myproject.dal.ejb.entity.RefStatus.expiration.lifespan" value= "10"/>
The setting produces no effects and the lifespan remains the default.
Do you know how I have to set the persistence.xml to successfully override the default expiration lifespan?
Setting the
<property name="hibernate.cache.infinispan.entity.expiration.lifespan" value= "10"/>
it works, but it affects all entity caches, and it is not what I want.
What follows is my application.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<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="myProject_dal_PU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/myProject-DataSource</jta-data-source>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.bytecode.use_reflection_optimizer" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_minimal_puts" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.infinispan.com.myenterprise.myproject.dal.ejb.entity.RefStatus.expiration.lifespan" value= "10"/>
</properties>
</persistence-unit>
</persistence>
Thank you.
If you are running within the application server, apart from the entity name, you have to provide the deployment name and unit too. So, all such expiration properties need to be prepended with: hibernate.cache.infinispan.<warname>.<unitname>.<FQN of entity>...
In your case, I don't know the name of your deployment, but with the unit and FQN that you mention, something like:
hibernate.cache.infinispan.<warname>.myProject_dal_PU.com.myenterprise.myproject.dal.ejb.entity.RefStatus.expiration.lifespan
Spent hours to find correct configuration. Apparently it is as following:
Hibernate property should be in the following format:
hibernate.cache.infinispan.<prefix>.<full-class-name>.<property-name> where:
<prefix> - by default it is in the name that you see in a sort of JNDI name. In case of Wildfly, it is ear-name.ear/ejb-jar-name.jar#persistence-unit-name
However, it can be controlled by hibernate.cache.region_prefix property. Set region_prefix to "" and ignore the prefix.
<property-name> - String as it appears in org.hibernate.cache.infinispan.InfinispanRegionFactory class and in official Infinispan documentation.
In short, official Infinispan documentation is correct only when you set hibernate.cache.region_prefix to ""
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>