Hibernate-JPA without XML class mapping - java

I'm currently learning Hibernate and JPA and I just stumbled upon the following issue:
I have an entity class called User, and this class is annotated with the #Entity (JPA) annotation. My persistence.xml file does NOT have a mapping for it, yet I can use it on my EntityManager without issues.
I just created another entity, called Comment (some packages below), this one is also annotated with #Entity and is also NOT on my persistence.xml file. This one however, throws a org.hibernate.MappingException: Unknown entity exception when used on the EntityManager.
My persistence.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<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/persistence_2_1.xsd">
<persistence-unit name="net.notfab.hibernatetest" transaction-type="RESOURCE_LOCAL">
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<!-- JPA Properties -->
<property name="javax.persistence.provider" value="org.hibernate.jpa.HibernatePersistenceProvider"/>
<property name="javax.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:mariadb://IP:PORT...."/>
<property name="javax.persistence.jdbc.user" value=""/>
<property name="javax.persistence.jdbc.password" value=""/>
<!-- Hibernate Properties -->
<property name="hibernate.connection.provider_class"
value="org.hibernate.hikaricp.internal.HikariCPConnectionProvider"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MariaDBDialect"/>
<property name="hibernate.connection.CharSet" value="utf8mb4_bin"/>
<property name="hibernate.connection.characterEncoding" value="utf8mb4_bin"/>
<property name="hibernate.connection.useUnicode" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.archive.autodetection" value="class, hbm" />
<!-- Hikari Properties -->
<property name="hibernate.hikari.minimumIdle" value="5"/>
<property name="hibernate.hikari.maximumPoolSize" value="10"/>
<property name="hibernate.hikari.idleTimeout" value="15000"/>
<property name="hibernate.hikari.leakDetectionThreshold" value="30000"/> <!-- 30 Seconds -->
<property name="hibernate.hikari.poolName" value="TestPool"/>
</properties>
</persistence-unit>
</persistence>
What may be causing this weird behavior?
Is there a way for me to continue using the annotated classes without having to declare them on the XML file? (It's 2018 already - Annotations are way better!).
Note: This question is similar but their end goal ended up being mapping on the XML, which I'm trying to avoid by all means. I'm also looking for an explanation to the above-mentioned behavior.
Edit: As requested by the comments, here is the full stacktrace https://hastebin.com/haguniheca.cs (as well as here https://hasteb.in/ipuzojoc.cs in case hastebin goes down again).
In this scenario, I'm not using Spring.
Edit 2: Here is my entity.
Edit 3: This is a gradle project, running off of a standalone (shaded) jar file on Java SE, currently using the following list of dependencies for persistence (among others):
compile group: 'org.hibernate', name: 'hibernate-hikaricp', version: '5.3.3.Final'
compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.2.6'
Edit 4: As per Eugen's comment I did some testing and the cause of the issue seems to be IntelliJ. By running the shaded jar file on it's own from the command line, the issue is fixed. (Maybe the classpath is different when running off of the application debug?). The question then becomes "how can I fix IntelliJ's run configuration for my app?".

Related

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.

Can it lead to problems while using the same Hibernate managed database for multiple projects?

I'm using Wildfly with Hibernate and I will have two different projects accessing the same database. Each project has its own persistence.xml, but the datasources within the persistence.xml are the same. Currently I have one project with these datasources. This looks like this:
Project A:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="MyProjectPersistenceUnit" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/myprojectDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
</persistence-unit>
<persistence-unit name="MyProjectLoggingUnit" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>java:jboss/datasources/myprojectDS</non-jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
</persistence-unit>
</persistence>
The additional project's persistence.xml will look like this:
Project B:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="MyProjectLoggingUnit" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/myprojectDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
</persistence-unit>
</persistence>
The first project uses both JTA and RESOURCE_LOCAL transactions, so I can handle logging "manually". The second project uses JTA only since I only do logging operation there. Project A does CRUD operations, Project B does create operations only. Both projects run within the same Wildfly server. Is it possible that any problem, maybe with locking in database, transactions in Wildfly or whatever, could occur between project A and project B while accessing the same database with the same datasources from different projects as I do it?
I don't think so, but I'm afraid that some 'side effects' could occur I don't know yet.
There should not be any problem, as Datasource is managed by jboss, it will allocate connection as per your configuration, locking can occure if you are using same row for processing from different projects but let database take care of that.
And there are different entities involved for not creating any problem like tho TCP connection is same/ shared sessions and transactions are diffrent for operation, spring and hibernate both are mature and best what they do, unless you messed with configurations ;), your looks good.
I agree that in principal you should not worry! BUT, since we are not dealing with magic and there is always an explanation when something does not work, the only case you should worry is a potential business coupling between the 2 applications and of course ends up in the data base. What I am trying to say, is that if Application1 which uses the same DB with Application2, performs things on entities that eventually are expected to be visible/ update for the logic on the other application, then yes there might be a chance that you will face some technical deadlocks (eventually pretty fine for a DB) but could be a problem on the business code level.
It is a matter of design and higher coupling, which happens to result in a technical coupling on the DB. I am not sure if I describe it correct, as a high level concern :)

how to automatic create table in jpa persistence xml file?

I am using eclipse IDE.I also try following two .but failed..when i manually create table in my mysql database then my complete program run fine... I want create table automatic with respect to entity class.
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.hbm2ddl.auto">update</property>
here my persistence file:
<?xml version="1.0" encoding="UTF-8"?>
<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/persistence_2_1.xsd">
<persistence-unit name="JpaTest2" transaction-type="RESOURCE_LOCAL">
<class>com.jpa.Employee</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/hibernate"/>
<property name="javax.persistence.jdbc.user" value="umar"/>
<property name="javax.persistence.jdbc.password" value="umar"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
Dont use Hibernate specific options. JPA 2.1 provides
javax.persistence.schema-generation.database.action
that can be set to "create", "drop", "drop-and-create", "none".
That way you keep your code JPA implementation independent
Check your entity. Did you miss #Table annotation? The exception clearly says that the table is missing 'hibernate.employee':
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'hibernate.employee' doesn't exist at ...
If you defined a naming strategy that prepends all tables with hibernate., then make sure that the tables are created in MySql.

OpenJpa in Apache Geronimo 3.0

I have a newbie question, so I hope you can help.
Currently as ORM tool I am using OpenJPA 2.2.1 .
MY CUrrent persistence UNit:
<?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" version="1.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="FleaCircus" transaction-type="JTA">
<description>Flea Circus</description>
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>FleaCircusOracleDS</jta-data-source>
<class>de.carmedialab.db.entities.ApplicationItem</class>
<class>de.carmedialab.db.entities.FleaResult</class>
<class>de.carmedialab.db.entities.FleaResultType</class>
<class>de.carmedialab.db.entities.ItemAttribute</class>
<class>de.carmedialab.db.entities.ItemGroup</class>
<class>de.carmedialab.db.entities.ItemType</class>
<class>de.carmedialab.db.entities.ItemTypeAttribute</class>
<class>de.carmedialab.db.entities.ItemTypeOperationAttribute</class>
<class>de.carmedialab.db.entities.Operation</class>
<class>de.carmedialab.db.entities.OperationAttribute</class>
<class>de.carmedialab.db.entities.OperationType</class>
<class>de.carmedialab.db.entities.Role</class>
<class>de.carmedialab.db.entities.UserAccount</class>
<class>de.carmedialab.db.entities.Measurement</class>
<class>de.carmedialab.db.entities.MeasurementType</class>
<class>de.carmedialab.db.entities.MeasurementAttribute</class>
<class>de.carmedialab.db.entities.MeasurementAttributeType</class>
<class>de.carmedialab.db.entities.Fleet</class>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings" value="validate" />
<property
name="openjpa.Compatibility.CheckDatabaseForCascadePersistToDetachedEntity"
value="true" />
<!--<property name="openjpa.Log"
value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE" />-->
</properties>
</persistence-unit>
<persistence-unit name="FleaCircusLocal" transaction-type="RESOURCE_LOCAL">
<description>Flea Circus</description>
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<non-jta-data-source>FleaCircusOracleDS</non-jta-data-source>
<class>de.carmedialab.db.entities.ApplicationItem</class>
<class>de.carmedialab.db.entities.FleaResult</class>
<class>de.carmedialab.db.entities.FleaResultType</class>
<class>de.carmedialab.db.entities.ItemAttribute</class>
<class>de.carmedialab.db.entities.ItemGroup</class>
<class>de.carmedialab.db.entities.ItemType</class>
<class>de.carmedialab.db.entities.ItemTypeAttribute</class>
<class>de.carmedialab.db.entities.ItemTypeOperationAttribute</class>
<class>de.carmedialab.db.entities.Operation</class>
<class>de.carmedialab.db.entities.OperationAttribute</class>
<class>de.carmedialab.db.entities.OperationType</class>
<class>de.carmedialab.db.entities.Role</class>
<class>de.carmedialab.db.entities.UserAccount</class>
<class>de.carmedialab.db.entities.Measurement</class>
<class>de.carmedialab.db.entities.MeasurementType</class>
<class>de.carmedialab.db.entities.MeasurementAttribute</class>
<class>de.carmedialab.db.entities.MeasurementAttributeType</class>
<class>de.carmedialab.db.entities.Fleet</class>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings" value="validate" />
<property
name="openjpa.Compatibility.CheckDatabaseForCascadePersistToDetachedEntity"
value="true" />
<!--<property name="openjpa.Log"
value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE" />-->
</properties>
</persistence-unit>
</persistence>
For the sake of simplicity, persistence-unit "FleaCircus" is what I use ( Container Managed Persistence ). FleaCircusLocal is another test pu I created , where I've created a sample stateless bean that basically starts a new transaction, persist an element and commit it.
However it doesn't sinchronize immediatly and customer complains about it.
Is there any way to make OpenJPA makes whats in context immediatly visible to the DB or is it impossible due to the nature as OpenJPA/JPA was thought ?
For me it is not a big deal since data is visible inside the container ( Apache Geronimo ) however for the customer it is important since he wants to connet using 3rd party tool ( eg. SQL Developer to and see if data was inserted or not .)

Infinispan - set per Entity expiration.lifespan

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 ""

Categories