I am using Hibernate JPA on a desktop application because generic SQL queries is almost impossible and I don't want to implement my own JPA.
I want to use non annotated entity classes because I'm using a library shared by the desktop app and an android app so I want to keep everything in XML. However Hibernate failed to build entity manager factory giving me the following error.
Caused by: org.hibernate.boot.MappingException: Unable to resolve explicitly named mapping-file : com/model/entity/TransferType.xml : origin(com/model/entity/TransferType.xml)
at org.hibernate.boot.model.process.internal.ScanningCoordinator.applyScanResultsToManagedResources(ScanningCoordinator.java:213)
at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:81)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:98)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:194)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:34)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:165)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:114)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:71)
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:52)
Here is the mapping file xml I used
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
version="2.0">
<entity class="app.model.DeviceType">
<table name="DEVICE_TYPE"
schema="my_schema"
catalog=""/>
<attributes>
<id name="type">
<column name="type"/>
</id>
</attributes>
</entity>
</entity-mappings>
How do I fixe this? What I am doing wrong in here?
Related
I keep table schema in this file tableaddress.orm.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="2.1"
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<entity class="Address">
<attributes>
<basic name="city" attribute-type="String" />
<basic name="country" attribute-type="int" />
<basic name="province" attribute-type="double" />
<basic name="postalCode" attribute-type="boolean">
</basic>
<basic name="street" attribute-type="String" />
</attributes>
</entity>
</entity-mappings>
Here is how I tried to create table using Hibernate
public class App
{
public static void main( String[] args )
{
Properties prop= new Properties();
prop.setProperty("hibernate.connection.url", "jdbc:mariadb:......");
prop.setProperty("dialect", "org.hibernate.dialect.MariaDB53Dialect");
prop.setProperty("hibernate.connection.username", "user");
prop.setProperty("hibernate.connection.password", "password");
prop.setProperty("hibernate.connection.driver_class", "org.mariadb.jdbc.Driver");
SessionFactory sessionFactory = new Configuration()
.addResource("tableaddress.orm.xml").addProperties(prop).buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.getTransaction().commit();
session.close();
}
}
It should work, there is no compile errors, but for some reason the table is not created
Error java.lang.NoClassDefFoundError: javax/transaction/SystemException
This is probably due to bug/feature in Hibernate.
The javax.transaction was removed from Hibernate (well, marked as "provided") in 5.0.4, but it was brought back in 5.0.7 (see https://hibernate.atlassian.net/browse/HHH-10307 :
"JTA no longer transitively provided (HHH-10178) causes problems for
apps not using JTA"
)
So assuming you are using 5.04, 5.0.5 or 5.0.6, your choices are to either upgrade Hibernate, or to add the following dependency :
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
I'm trying to implement Axon app using JPA Event Store and mysql database. Hibernate is automatically generating all the tables and it works OK so far.
My question is - can I replace hibernate_sequence mysql table for AUTO_INCREMENT columns in Mysql. I guess in order to do this I would need to modify source code of Axon, since I cannot find other configurable way to modify #Id annotation for Domain event #Entity or other entitites?
UPDATE
OK, i managed to do it by placing new file in src\main\resources\META-INF\orm.xml with following code:
<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
version="2.0">
<mapped-superclass class="org.axonframework.eventhandling.AbstractSequencedDomainEventEntry" access="FIELD">
<attributes>
<id name="globalIndex">
<generated-value strategy="IDENTITY"/>
</id>
</attributes>
</mapped-superclass>
<entity class="org.axonframework.modelling.saga.repository.jpa.AssociationValueEntry" access="FIELD">
<attributes>
<id name="id">
<generated-value strategy="IDENTITY"/>
</id>
</attributes>
</entity>
</entity-mappings>
You could make this adjustment through code, that's true.
It is however more straightforward to specify an orm.xml file in your project which for some tables (the domain_event_entry table in your scenario I assume) can adjust certain columns.
In there you should be able to adjust the sequence generator to what you desire it to be.
Hope this helps!
I am developing a JPA application which requires to be able to access different schemas on the same database (i.e. DB2/Oracle). I want all of my entities to be registered in the persistence.xml file (<class>) and be able to define which ones belong to certain schemas.
I know it is possible to use java annotations, however this is a product which will need the end user to configure that accordingly (hence why I want to be able to achieve this in an xml file).
Currently I have found an example like this:
orm.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>SECURITY</schema>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="jpa.sample.plain">
<mapping-file>custom-orm.xml</mapping-file>
<class>com.reds.model.Role</class>
<class>com.reds.model.User</class>
<properties>
<property name="javax.persistence.target-database" value="PostgreSQL" />
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://127.0.0.1:5432/security" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="password" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="none" />
<property name="eclipselink.weaving" value="false" />
<!-- <property name="eclipselink.ddl-generation.output-mode"
value="database" /> -->
<property name="eclipselink.logging.level" value="INFO"/>
</properties>
</persistence-unit>
</persistence>
In the above files, from my understanding the schema "SECURITY" is set on the persistence unit that includes the orm.xml mapping file (makes it the default which an annotation can change?). But this makes the schema be implicitly "SECURITY" for both classes listed in persistence.xml.
Contrary to the above I need:
A way to list the schema on a subset of classes in a persistence unit in an efficient way (unless if the only way is to do the entity mappings manually in the orm.xml which is something I wish to avoid and the end user would too)
Keep this away from vendor specific xml files or java implementations if possible (keep to JPA standard)
Side question: Would this allow a JPQL query to go through transparently for 2 entities with different schemas?
Details of project:
Hibernate 5.1, JPA 2.1
DB2/Oracle
EDIT:
I found this link which helped me set up my orm.xml: https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/xml-overriding.html
Posted below is the most relevant excerpt:
3.1.2. Entity level metadata
You can either define or override metadata informations on a given entity.
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappin(1)gs
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0">
<package>o(2)rg.hibernate.test.annotations.reflection</package>
<entity cl(3)ass="Administration" access="PROPERTY" metadata-complete="true">
<table(4) name="tbl_admin">
<unique-constraint>
<column-name>firstname</column-name>
<column-name>lastname</column-name>
</unique-constraint>
</table>
<secon(5)dary-table name="admin2">
<primary-key-join-column name="admin_id" referenced-column-name="id"/>
<unique-constraint>
<column-name>address</column-name>
</unique-constraint>
</secondary-table>
<id-cl(6)ass class="SocialSecurityNumber"/>
<inher(7)itance strategy="JOINED"/>
<seque(8)nce-generator name="seqhilo" sequence-name="seqhilo"/>
<table(9)-generator name="table" table="tablehilo"/>
...
</entity>
<entity class="PostalAdministration">
<prima(10)ry-key-join-column name="id"/>
...
</entity>
</entity-mappings>
1 entity-mappings: entity-mappings is the root element for all XML files. You must declare the xml schema, the schema file is included in the hibernate-annotations.jar file, no internet access will be processed by Hibernate Annotations.
2 package (optional): default package used for all non qualified class names in the given deployment descriptor file.
3 entity: desribes an entity.
metadata-complete defines whether the metadata description for this element is complete or not (in other words, if annotations present at the class level should be considered or not).
An entity has to have a class attribute refering the java class the metadata applies on.
You can overrides entity name through the name attribute, if none is defined and if an #Entity.name is present, then it is used (provided that metadata complete is not set).
For metadata complete (see below) element, you can define an access (either FIELD or PROPERTY (default)). For non medatada complete element, if access is not defined, the #Id position will lead position, if access is defined, the value is used.
4 table: you can declare table properties (name, schema, catalog), if none is defined, the java annotation is used.
You can define one or several unique constraints as seen in the example
5 secondary-table: defines a secondary table very much like a regular table except that you can define the primary key / foreign key column(s) through the primary-key-join-column element. On non metadata complete, annotation secondary tables are used only if there is no secondary-table definition, annotations are ignored otherwise.
6 id-class: defines the id class in a similar way #IdClass does
7 inheritance: defines the inheritance strategy (JOINED, TABLE_PER_CLASS, SINGLE_TABLE), Available only at the root entity level
8 sequence-generator: defines a sequence generator
9 table-generator: defines a table generator
10 primary-key-join-column: defines the primary key join column for sub entities when JOINED inheritance strategy is used
No, you can't do this via the orm.xml or persistence.xml files.
That said, you can do something similar by specifying the non-standard schema in your #Table annotation on each individual persistence object.
#Entity
#Table(name = "PERSON", schema="SOME_OTHER_SCHEMA")
public class Person {
. . .
}
I'm trying based on some examples and Hibernate documentation for mapping a Stored Procedure, I just need to insert some data wich is not for a single table, but I got the message:
Could not parse mapping document from resource
The mapping file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Data">
<id column="col_id" name="dataId">
<generator class="assigned" />
</id>
<property column="col_liq" name="dataLiq" />
<property column="col_td" name="dataTd" />
<property column="col_numdcto" name="dataNumDoc" />
<sql-insert callable="true" check="none">
{call sp_update_data(?,?,?,?)}
</sql-insert>
</class>
</hibernate-mapping>
The "Data" object is just a POJO.
I will appreciate any idea or sugestion.
just to let others to know how it works due finally I did it.
The mapping is correct with just one point, Hibernate will set the Id as the last field, so the procedure should get it in that position, at least that you do some "trick".
In Java when calling the procedure is like a normal save, the rest is like working with a normal entity.
I have the following class:
package lt.vic.valdos.domain.valda;
public class Valda implements java.io.Serializable {
private long id;
private Long valdosKodas;
public long getId() {
return id;
}
public Long getValdosKodas() {
return valdosKodas;
}
}
and the following orm.xml:
<?xml version="1.0"?>
<entity-mappings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_1.xsd"
version="2.1">
<entity class="lt.vic.valdos.domain.valda.Valda">
<table name="VALDOS" schema="VLD" />
<attributes>
<id name="id" />
<basic name="id">
<column name="vld_id" />
<return-insert return-only="true" />
</basic>
<basic name="valdosKodas">
<column name="valdos_kodas" />
</basic>
</attributes>
</entity>
</entity-mappings>
When I deploy this in glassfish, i get the following error:
Exception [EclipseLink-7215] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Could not load the field named [id] on the class [class lt.vic.valdos.domain.valda.Valda]. Ensure there is a corresponding field with that name defined on the class.
The class is in a jar that is included into a web application as a maven dependency. The orm.xml is in /WEB-INF/classes/META-INF of the web application.
What am I doing wrong?
Figured this one out myself. For some reason EclipseLink requires a setter on a class. Once I add private setters everything seems fine. Why the setters are needed (mapping accessors should default to FIELD) remains a mystery but it is not that important for me. Adding access="FIELD" to all entity attributes also fixes the problem without the setters.
You should be specifying the id as generated using the IDENTITY strategy:
<id name="id">
<column name="vld_id"/>
<generated-value strategy="IDENTITY"/>
</id>
This strategy will automatically read the database provided id back into the new object upon successful commit. The EclipseLink returning statement functionality is only applicable to basic mappings because id is already covered by Identity ID generation.
I think you have to add the column description for the id column to your id element, instead of using an extra basic element. As in <id name="id"> <column name="vld_id" /> ... </id>, without an extra <basic name="id"> ....
From my own experience (some time ago now), it's probably easier to use annotations to define your mappings.