what is gradle missing to map hibernate? - java

I have unittest to my java project.
My code uses hibernate.
When i run the test using junit - everything passes.
When I run the test using gradle - I get a mapping error:
Caused by: org.hibernate.MappingException: Unknown entity: linqmap.users.interfaces.model.UserRecord
and the class:
#Entity
#Table(name = "users")
public class UserRecord implements Serializable {
private static final long serialVersionUID = 1L;
public static short CLASS_VERSION = 3;
#Transient
public short objectVersion = CLASS_VERSION;
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "id")
public long ID;
#Column(name = "user_name")
public String userName;
#Column(name = "email")
public String email;
#Column(name = "full_name") // will be deprecated in the future
public String fullName;
#Column(name = "password")
public String password;
and a config file:
<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_1_0.xsd"
version="1.0">
<persistence-unit name="UsersDB">
<!-- The provider only needs to be set if you use several JPA providers <provider>org.hibernate.ejb.HibernatePersistence</provider> -->
<properties>
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.archive.autodetection" value="class, hbm" />
<!-- SQL stdout logging <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/>
<property name="use_sql_comments" value="true"/> -->
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.url" value="dbc:postgresql://localhost:9992/israel" />
what can be missing in gradle?

I think the problem is not really with gradle. It's with the fact that the JPA spec stupidly requires that the classes of the entities are in the same jar/directory as the persistence.xml file. And since Gradle doesn't store the "compiled" resources in the same output directory as the compiled classes, Hibernate doesn't find the mapped entities.
Add this line to your gradle build, and it will probably be fine
sourceSets.main.output.resourcesDir = sourceSets.main.output.classesDir

Related

Do I need to create table for Hibernate TableGenerator on my own?

I am trying to figure out the different types of generating primary keys for classes that inherit from a superclass, I am using the embedded H2 database, the data is stored in a file. Everything worked well, the entities that I had previously created manually in the database were loaded, but when I tried to save a new entity using Hibernate, I got an error
Table "ID_GENERATOR" not found.
I wonder, should I create the table for "ID_GENERATOR" table generator manually? I thought Hibernate creates it automatically
Here' my superclass:
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class FundEvent implements Comparable<FundEvent>{
#Id
#TableGenerator(name = "id_generator")
#GeneratedValue(strategy = GenerationType.TABLE, generator = "id_generator")
protected int id;
#Column(name = "amount")
protected int amount;
#Column(name = "deadline")
protected Date deadline;
#ManyToOne
#JoinColumn(name = "user_id")
protected User user;
//getters and setters
And here's Entity class object of which I'm trying to save:
#Entity
#Table(name = "purchases")
public class Purchase extends FundEvent{
#Column(name = "goal")
private String goal;
#Column(name = "bought")
private boolean bought;
#Column(name = "removed")
private boolean removed;
#Transient
private int activeAmount;
//getters and setters
Do I miss something?
UPD: Here's my hibernate.cfg.xml. Note, i'm not using Spring, just Hibernate
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:file:/home/vetal22331122/data_for_purch</property>
<property name="connection.username"></property>
<property name="connection.password"></property>
<!-- JDBC connection pool settings ... using built-in test pool -->
<property name="connection.pool_size">2</property>
<!-- Select our SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">none</property>
<!-- dbcp connection pool configuration -->
<property name="hibernate.dbcp.initialSize">5</property>
<property name="hibernate.dbcp.maxTotal">20</property>
<property name="hibernate.dbcp.maxIdle">10</property>
<property name="hibernate.dbcp.minIdle">5</property>
<property name="hibernate.dbcp.maxWaitMillis">-1</property>
<mapping class="entities.Purchase"/>
<!--<mapping class="entities.Payment"/>-->
<mapping class="entities.User"/>
</session-factory>
</hibernate-configuration>
Javadoc of TableGenerator showing an example of it filled with almost all the properties, try to fill in every property of the annotation and run again: https://docs.oracle.com/javaee/6/api/javax/persistence/TableGenerator.html

SequenceGenerator does not work in JUnit test?

I try to test the persistence of some entities with an in-memory H2 DB but I recognized that #SequenceGenerator will never be invoked as it should be, neither when running by build platform, nor when running it with RunAs->JUnit test in Eclipse.
What I can say for sure is that the sequences are generated inside the H2 DB. I can even select them when I connect to this generated H2. So it's definitely not a problem inside H2 but with Hibernate.
(Usually Hibernate automatically assigns an ID when persisting an Entity which needs one).
The entity
#Entity
#Table(name = "HOUSE_USERDATA")
public class UserData {
#Id
#Column(name = "HU_ID")
#GeneratedValue(generator = "SEQ_HOUSE_USERDATA", strategy = GenerationType.SEQUENCE)
#SequenceGenerator(sequenceName = "SEQ_HOUSE_USERDATA", name = "SEQ_HOUSE_USERDATA", allocationSize = 2)
private Long huId;
#Column(name = "HU_DATA")
#Size(max = 1000)
private String m_data;
#ManyToOne
#JoinColumn(name = "HR_ID")
private Registry m_registry;
//more code [...]
}
The reference in the referencing Entity...
#OneToMany(mappedBy = "registry")
private List<UserData> userDataList;
The persistence unit...
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.foo.bar.all.entity</class>
<!-- all entity references -->
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url"
value="jdbc:h2:inmemory;INIT=runscript from 'classpath:testscripts/drop_h2.sql'\;runscript from 'classpath:testscripts/create.sql'"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.use_sql_comments" value="true" />
</properties>
</persistence-unit>
The invocation in JUnit test...
Registry registry = new Registry();
registry.setClientId("clientId");
List<UserData> userDataList = new ArrayList<>();
UserData userData1 = new UserData();
userData1.setData("User defined data 1.");
userData1.setRegistry(registry);
UserData userData2 = new UserData();
userData2.setData("User defined data 2.");
userData2.setRegistry(registry);
userDataList.add(userData1);
userDataList.add(userData2);
registry.setUserDataList(userDataList);
entityManager.persist(registry);
Registry result = entityManager.find(Registry.class, "clientId");
//MUST NOT BE NULL, BUT IS NULL
assertThat(result.getUserDataList().get(0).getId(), is(not(nullValue())))
Other values are persisted properly. Only the IDs were not generated. (I wonder why this test works at all for all the other values since the ID is defined as NOT NULL in the generated DB, so there should be a persistence exception or something else).
Any ides why the sequence generator does not generate anything (I tried GenerationType.AUTO as well, but no difference)?
When you are doing entityManager.persist(registry) that is what it is going to do, store the Registry and check all the mappings for that class. It will encounter the collection of UserData objects, but because there is no cascade property matching the PERSIST it will not store the UserData objects.
It will only store the top level Registry object. If you want to change this add cascade={CascadeType.ALL} or at least cascade={CascadeType.PERSIST} to the #OneToMany annotation, to tell Hibernate it also needs to check the collection for new elements and persist those.
Or first store the UserData elements, before storing the Registry.

PostgreSQL and Hibernate JPA not working

I'm trying to use JPA in Wildfly (which uses Hibernate) with PostgreSQL. I turned on hibernate.show_sql so I can execute the same query in PgAdmin III.
The query is this one (EDIT: issuemanager_sch is the schema. Without it even in PgAdmin the query fails with "relation does not exist" error):
select issuetypet0_.id_issue_type as id_issue1_3_, issuetypet0_.name as name2_3_ from issuemanager_sch.issue_type issuetypet0_
When executed by Hibernate this is showed in both PostgreSQL log and Wildfly log :
relation "issuemanager_sch.issue_type" does not exist character 87
However, when I copy (to grant I'm executing the exact same query), paste and run the query in PgAdmin III it's executed normally and I get the results.
What could possibly be wrong with my configurations? (I tried with both quoted and unquoted queries and the results are the same: fails for Hibernate, works in PgAdmin III)
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
<persistence-unit name="PersistenceManager" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>java:/datasources/issuemanager_pg</non-jta-data-source>
<class>com.im.issuerepository.domain.IssueTO</class>
<class>com.im.issuerepository.domain.IssueTypeTO</class>
<class>com.im.userrepository.domain.UserTO</class>
<class>com.im.userrepository.domain.GroupTO</class>
<class>com.im.userrepository.domain.RoleTO</class>
<validation-mode>NONE</validation-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.default_schema" value="issuemanager_sch"/>
</properties>
</persistence-unit>
</persistence>
EDIT: issue_type table:
CREATE TABLE issuemanager_sch.issue_type
(
id_issue_type bigint NOT NULL DEFAULT nextval('issuemanager_sch.issue_type_seq'::regclass),
name text NOT NULL,
CONSTRAINT "PK_ISSUE_TYPE" PRIMARY KEY (id_issue_type)
)
EDIT: IssueTypeTO mapping:
#Entity
#Table(name = "issue_type")
public class IssueTypeTO implements Serializable{
#Id
#Column(name = "id_issue_type")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "issue_type_seq")
#SequenceGenerator(name = "issue_type_seq", sequenceName = "issue_type_seq", allocationSize = 1)
private Long idIssueType;
#Column(name = "name", length = 45)
private String name;
// getters and setters
}

Getting "java.lang.UnsupportedOperationException:"

I created the small JPA project to persist a Student record. I use Oracle database. I use the OpenJPA as the JPa provider.
I have created the Table student and relevant sequences correctly.
Student Entity class
#Entity
#Table(name = "Student")
public class Student implements Serializable {
private int id;
private String name;
private static final long serialVersionUID = 1L;
public Student() {
super();
}
#Id
#Column(name = "ID")
#SequenceGenerator(name = "TRAIN_SEQ", sequenceName = "STUDENT_SEQ")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TRAIN_SEQ")
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "NAME")
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
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="JPAOracleDemo">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>com.jpa.demo.model.Student</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:oracle:thin:#TEST:50111:TESTPEGAD1" />
<property name="openjpa.ConnectionDriverName" value="oracle.jdbc.driver.OracleDriver" />
<property name="openjpa.ConnectionUserName" value="admin" />
<property name="openjpa.ConnectionPassword" value="admin" />
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
<property name="openjpa.jdbc.Schema" value="MYSCHEMA" />
</properties>
</persistence-unit>
</persistence>
Client Class
OpenJPAEntityManager em = JPAUtil.getEntityManager();
OpenJPAEntityTransaction tx = em.getTransaction();
tx.begin();
// Create the instance of Employee Entity class
Student student = new Student();
student.setName("A.Ramesh");
// JPA API to store the Student instance on the database.
em.persist(student);
tx.commit();
em.close();
System.out.println("Done...");
Util class
private static OpenJPAEntityManagerFactory emf = OpenJPAPersistence
.createEntityManagerFactory("JPAOracleDemo", "META-INF/persistence.xml");
private static OpenJPAEntityManager entManager;
/**
* No need to create any instance for this Util.
*/
private JPAUtil() {
}
/**
* Get {#link EntityManager}.
*
* #return the {#link EntityManager}
*/
public static OpenJPAEntityManager getEntityManager() {
if (entManager == null || !entManager.isOpen()) {
entManager = emf.createEntityManager();
}
return entManager;
}
The data persist in the student table successfully, but I have the bellow error
Exception in thread "Attachment 60230" java.lang.UnsupportedOperationException: cannot get the capability, performing dispose of the retransforming environment
at com.ibm.tools.attach.javaSE.Attachment.loadAgentLibraryImpl(Native Method)
at com.ibm.tools.attach.javaSE.Attachment.loadAgentLibrary(Attachment.java:253)
at com.ibm.tools.attach.javaSE.Attachment.parseLoadAgent(Attachment.java:235)
at com.ibm.tools.attach.javaSE.Attachment.doCommand(Attachment.java:154)
at com.ibm.tools.attach.javaSE.Attachment.run(Attachment.java:116)
Exception in thread "main" java.lang.UnsupportedOperationException: cannot get the capability, performing dispose of the retransforming environment
at sun.instrument.InstrumentationImpl.isRetransformClassesSupported0(Native Method)
at sun.instrument.InstrumentationImpl.isRetransformClassesSupported(InstrumentationImpl.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.apache.openjpa.enhance.ClassRedefiner.canRedefineClasses(ClassRedefiner.java:123)
at org.apache.openjpa.enhance.ManagedClassSubclasser.prepareUnenhancedClasses(ManagedClassSubclasser.java:122)
at org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:304)
at org.apache.openjpa.kernel.AbstractBrokerFactory.initializeBroker(AbstractBrokerFactory.java:228)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:202)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:213)
at com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:45)
at com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:30)
at com.jpa.demo.util.JPAUtil.getEntityManager(JPAUtil.java:32)
at com.jpa.demo.client.JPAClient.main(JPAClient.java:13)
1045 JPAOracleDemo INFO [main] openjpa.Enhance - Creating subclass for "[class com.jpa.demo.model.Student]". This means that your application will be less efficient and will consume more memory than it would if you ran the OpenJPA enhancer. Additionally, lazy loading will not be available for one-to-one and many-to-one persistent attributes in types using field access; they will be loaded eagerly instead.
Done...
Java version
JDK 1.6
Anybody please let me know what is the issue here?
Updated:
I used the IBM Rational Software Architect for Websphere Software for this development. this problem is with this IDE. When I create the JPA project by default it adds the IBM jre. I just removed the IBM jre and tried with the SUN jre then it was success. Please let me know why this function does not support with IBM jre?
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
For starters, get rid of that property.
This is my enhancer template, this works properly for OPENJPA:
`
<path id="enhance.cp">
<pathelement location="${basedir}${file.separator}${build.dir}" />
<fileset dir="${basedir}${file.separator}ext_libs/">
<include name="**/*.jar" />
</fileset>
</path>
<property name="cp" refid="enhance.cp" />
<target name="openjpa.libs.check" unless="openjpa.libs">
<fail message="Please set -Dopenjpa.libs in your builder configuration!" />
</target>
<target name="build.dir.check" unless="build.dir">
<fail message="Please set -Dbuild.dir in your builder configuration!" />
</target>
<target name="enhance" depends="openjpa.libs.check, build.dir.check">
<echo message="${cp}" />
<taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask">
<classpath refid="enhance.cp" />
</taskdef>
<openjpac>
<classpath refid="enhance.cp" />
<configpropertiesFile="${basedir}${file.separator}src${file.separator}main${file.separator} resources${file.separator}META-INF${file.separator}persistence.xml" />
</openjpac>
</target>
`
The JPA spec requires some type of monitoring of Entity objects, but the spec does not define how to implement this monitoring. Some JPA providers auto-generate new subclasses or proxy objects that front the user's Entity objects at runtime, while others use byte-code weaving technologies to enhance the actual Entity class objects. OpenJPA supports both mechanisms, but strongly suggests only using the byte-code weaving enhancement. The subclassing support (as provided by OpenJPA) is not recommended (and is disabled by default in OpenJPA 2.0 and beyond).(Source: http://openjpa.apache.org/entity-enhancement.html)
The cause of this issue is I used the subclassing support for the entity enhancement but that is disabled by default in OpenJPA2.0 and beyond.
I found the solution for this issue. We have to enhance the entity class at run time by providing a javaagent when launching the JVM that OpenJPA is going run in.
I put something like the following as a JVM argument
-javaagent:C:/OpenJPA/apache-openjpa-2.0.0/openjpa-2.0.0.jar
And I removed the bellow line from persistence.xml
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
Working persistence.xml
<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="DataSourceDemo">
<jta-data-source>oracleDS</jta-data-source>
<class>com.auditlog.model.BatchPrint</class>
<properties>
<property name="openjpa.ConnectionUserName" value="admin" />
<property name="openjpa.ConnectionPassword" value="test" />
<property name="openjpa.jdbc.Schema" value="defaultScheme" />
</properties>
</persistence-unit>
</persistence>

One table is not being created by toplink

I'm feeling really stupid having to ask this. But I've been looking at my code for 4 hours and can't figure it out. I have rebuild my database several times and can't get it to work.
One of my tables isn't being created for some reason. I have 4 tables game, developer, gameimage and user. User isn't being created but the other are being created perfectly and working. I'm sure it's a stupid mistake but I just don't see it.
If someone could just tell me why this might be happening that would be great.
I'm using toplink
Here is my code:
persistence xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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_1_0.xsd">
<persistence-unit name="GameDatabasePU" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>domainmodel.Game</class>
<class>domainmodel.GameImage</class>
<class>domainmodel.Developer</class>
<class>domainmodel.User</class>
<properties>
<property name="toplink.jdbc.user" value="app"/>
<property name="toplink.jdbc.password" value="app"/>
<property name="toplink.jdbc.url" value="jdbc:derby://localhost:1527/Gamedatabase;create=true"/>
<property name="toplink.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="toplink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>
User:
#Entity
public class User {
#Id
private String username;
private String password;
private String firstName;
private String surname;
public User() {
}
public User(String naam, String pas){
setUsername(naam);
setPassword(pas);
}
public User(String naam, String pas, String firstName, String surname){
setUsername(naam);
setPassword(pas);
setFirstName(firstName);
setSurname(surname);
}
public void setUsername(String naam){
this.username=naam;
}
//methods
}
Not realy an answer but more some tips to narrow the problem down.
1) Try removing all other classes from your persistence.xml (comment out annotations on other classes)
Maybe the problem is in another class and the output is misleading.
2) Try setting the debug/output level to another level (DEBUG, FINE, FINEST) and get the JPA provider to expose queries.
For TopLink I think adding this to your prersistence properties section will do the trick:
<property name="toplink.logging.level" value="FINEST" />
3) Which database are you using? MySql, PostgreSQL, HSQL, SQL-server?
Some databases don't (fully) support some things.
4) Shouldn't matter, but anyway;
Annotate your User class with #Table(name = "user") or #Table(name = "usera") this will make certain the table name isn't the problem.

Categories

Resources