Hibernate/H2 #OneToMany "Referential integrity constraint violation" on remove of child? - java

Hello I have a rather simple relationship.
A Patient can have several Measurements. I used a H2 file database and Hibernate.
The Problem:
When I try to remove a Measurement from a Patient I get a the following Error.
Referential integrity constraint violation: "FK_O423U89KR6K78NNG1PO0ISDF6: PUBLIC.PATIENTVO_MEASUREMENTVO FOREIGN KEY(MEASUREMENTS_ID) REFERENCES PUBLIC.MEASUREMENTVO(ID) (X'3c2b9ee868f645c5a5a743c2a409ab5e')"; SQL statement:
delete from MeasurementVO where id=? [23503-185]
The Patient part of the Relationship:
#OneToMany(orphanRemoval=true, cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}, mappedBy = "patient", fetch = FetchType.EAGER)
public List<MeasurementVO> getMeasurements() {
return measurements;
}
The Measurement Part of the Relationship:
#ManyToOne
#JoinColumn
public PatientVO getPatient() {
return patient.get();
}
The function which should delete a Measurement:
#Override
#Transactional
public boolean removeMeasurementFromPatient(PatientVO patientVO, MeasurementVO measurementVO) {
EntityManager manager = emProvider.get();
PatientVO patientAlreadyInDB = manager.find(PatientVO.class, patientVO.getPatientId());
if (patientAlreadyInDB != null) {
patientAlreadyInDB.getMeasurements().removeIf(measurement -> measurement.getId().equals(measurementVO.getId()));
manager.merge(patientAlreadyInDB);
return true;
} else {
return false;
}
}
And the Persistence XML:
<?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_1_0.xsd" version="1.0">
<persistence-unit name="db" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>ch.fhnw.ima.doggait.vo.PatientVO</class>
<class>ch.fhnw.ima.doggait.vo.MeasurementVO</class>
<class>ch.fhnw.ima.doggait.vo.MeasurementAttributesVO</class>
<class>ch.fhnw.ima.doggait.vo.TimeMark</class>
<properties>
<property name="connection.driver_class" value="org.h2.Driver"/>
<!-- <property name="hibernate.connection.url" value="jdbc:h2:mem:db"/>-->
<property name="hibernate.connection.url" value="jdbc:h2:file:./database/dogdatabase"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!--<property name="hibernate.hbm2ddl.auto" value="create-drop"/>-->
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
Does somebody has a hint why I am not able to remove a Measurement from a patient and then persist him/her?

From the name of the table whose constraint is being violated (PATIENTVO_MEASUREMENTVO), seems like you have an intermediate table to implement the relation. This is normally used in many to many relationships.
Being a one to many relationship why not just adding a foreign key from the Measurement to Patient?

Related

hibernate gen table error org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build()" because "entityManagerFactoryBuilder" is null

I fail to generate table from entity in eclipse with error org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build()" because "entityManagerFactoryBuilder" is null
I have three hibernate classes :
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
abstract public class GameBean implements Serializable {
private static final long serialVersionUID = -8690022943103849312L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
protected GameBean(){
}
}
#Entity
#Table(name="CheckersGame")
#PrimaryKeyJoinColumn(name="id")
public class CheckersGameBean extends GameBean{
/**
*
*/
private static final long serialVersionUID = -6448336204266253962L;
protected CheckersGameBean(){
super();
}
}
#Entity
#Table(name="ChessGame")
#PrimaryKeyJoinColumn(name="id")
public class ChessGameBean extends GameBean {
/**
*
*/
private static final long serialVersionUID = 3921250444757041509L;
protected ChessGameBean(){
super();
}
}
antlr-2.7.7.jar
byte-buddy-1.10.10.jar
classmate-1.5.1.jar
commons-beanutils-1.9.3.jar
commons-collections.jar
commons-dbcp-1.4.jar
commons-lang.jar
commons-logging-1.1.1.jar
dom4j-2.1.3.jar
ezmorph.jar
FastInfoset-1.2.15.jar
hibernate-commons-annotations-5.1.0.Final.jar
hibernate-core-5.4.15.Final.jar
hibernate-envers-5.4.15.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
hibernate-jpamodelgen-5.4.15.Final.jar
istack-commons-runtime-3.0.7.jar
jandex-2.1.3.Final.jar
javassist-3.24.0-GA.jar
javax.activation_1.1.0.v201211130549.jar
javax.activation-api-1.2.0.jar
javax.persistence-api-2.2.jar
javax.xml_1.3.4.v201005080400.jar
javax.xml.bind_2.2.0.v201105210648.jar
jaxb-api-2.3.1.jar
jaxb-runtime-2.3.1.jar
jboss-logging-3.3.2.Final.jar
jboss-transaction-api_1.2_spec-1.1.1.Final.jar
json-lib-2.2.2-jdk15.jar
log4j.properties
mysql-connector-java-8.0.30.jar
stax-ex-1.8.jar
txw2-2.3.1.jar
persistence.xml
<?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="JPAUNIT-BOARDGAMES" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider
<class>com.strategisina.ontheboard.bean.CheckersGameBean</class>
<class>com.strategisina.ontheboard.bean.ChessGameBean</class>
<class>com.strategisina.ontheboard.bean.GameBean</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/DATABASE"/>
<property name="javax.persistence.jdbc.user" value="USER"/>
<property name="javax.persistence.jdbc.password" value="PASSWORD"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
</properties>
</persistence-unit>
</persistence>
When I try to generate the tables with the JPA Tool/Generate Tables from Entries, the above error appears and no generation is done.
I would be really cool to get help with that, its a little time I'm on it !
I succeed in making it work. I used in Console Configuration a Annotation (Jdk 1.5+) type and a Hibernate Version 4.3. And then I succeeded in generating the tables with this console configuration. As I didn't understand what was wrong, I can't explain the solution. It works as well with JPA, with persistence.xml as follows
<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" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="JPAUNIT" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>```

Java EE/ JPA #PersistenceContext(unitName = ) doesn't inject Hibernate entity manager implementation

Currently, I learn the Java EE JPA specification. I am using Hibernate as JPA implementation. And I have the next issue:
I have a simple entity
#Entity
public class Book {
#Id
#GeneratedValue
private Long id;
private String title;
private String description;
private Float unitCost;
public Book() {
}
// getters and setters
}
And a simple Service:
public class BookService {
#PersistenceUnit(unitName = "book_store")
private EntityManager entityManager;
public void create(Book book) {
entityManager.persist(book);
entityManager.flush();
}
}
The persistence.xml has next view:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<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_2.xsd"
version="2.2">
<persistence-unit name="book_store">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.example.jpatest1.Book</class>
<properties>
<property name="javax.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password"
value="somePasss"/>
<property name="javax.persistence.jdbc.user" value="sammy"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/book_store?
autoReconnect=true&useSSL=false"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>
And I don't understand why the Hibernate Session don't inject into BookService. In book service as EntityManager I got org.jboss.as.TransactionScopedEntityManager instead of SessionImpl from Hibernate. Why using #PersistenceContext(unitName = ) I don't get Hibernate EntityManager implementation?
Also, I pin link on github: link on code source
The type of the object field entityManager is EntityManager, so you get injected what you declared in that field.
To get session from EntityManager, you can try this:
Session session = entityManager.unwrap(Session.class);

JPA ManyToMany anotation for not load all items in set

I have User class and BattleReportILogItem class. This class (User, BattleReportILogItem) are #Entity.
User have 0..N BattleReportILogItem.
USER
#Entity
#Table(name = DomainConstant.TABLE_USER)
public class User implements Serializable {
#Id
#Column(name = DomainConstant.DOMAIN_USER_ID)
#GeneratedValue
private Long userId;
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name = DomainConstant.VIEW_USER_BATTLE_LOGS, joinColumns = {
#JoinColumn(name = DomainConstant.DOMAIN_USER_ID)}, inverseJoinColumns = {
#JoinColumn(name = DomainConstant.DOMAIN_BATTLE_REPORT_ID)})
private Set<BattleReportILogItem> setOfBattleLogs = new HashSet<>();
....(other stuff, get and set methods...)
BattleReportILogItem
#Entity
#Table(name = DomainConstant.TABLE_BATTLE_REPORT)
public class BattleReportILogItem implements Serializable {
#Id
#GeneratedValue
#Column(name = DomainConstant.DOMAIN_BATTLE_REPORT_ID)
private Long BattleReportILogItemId;
#ManyToMany(mappedBy = "setOfBattleLogs")
private Set<User> setOfBattleLogs = new HashSet<>();
....(other stuff, get and set methods...)
The problem is, that I load User program loads all data in private Set<BattleReportILogItem> setOfBattleLogs = new HashSet<>();. This mean 1 000 000 000 items in my set setOfBattleLogs. I don't want load data to this set. For load data i have BattleReportLogItemDao DAO.
Is there any solution how to NOT LOAD DATA to my set?
I hope, you understand me... :-))
Thank you for your help.
EDIT persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="com.donutek" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/db"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.validator.apply_to_ddl" value="true" />
<property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
<property name="hibernate.c3p0.min_size" value="5"/>
<property name="hibernate.c3p0.max_size" value="20"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="300"/>
</properties>
</persistence-unit>
</persistence>
EDIT 2:
For load user I am using the code:
#Override
public User findByEmail(String email) {
TypedQuery<User> q = em.createQuery("SELECT u FROM " + User.class.getSimpleName() + " u WHERE u.email = :uemail", User.class);
q.setParameter("uemail", email);
try {
return q.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
You can use the parameter fetchtype Lazy. Now your strategy seems to be Eager.

Hibernate Auto Detection in Persistence.xml Not Working

I've read Do I need <class> elements in persistence.xml? and How to auto detect entities in JPA 2.0 and followed their tag useage in my persistence.xml, but Entitys are not being auto detected by Hibernate. When I remove the <class> tag this no longer works and I get a MappingException. For some reason I can't seem to enable auto detection. NOTE this is a stand-alone hibernate application (shouldn't matter as far as I know). I have this example:
Persistence.xml:
<?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="Test_Project" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.gmail.physicistsarah.gradletestproject.core.Person</class>
<!--Exclude unlisted class detection-->
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.archive.autodetection" value="class, hbm"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test_project_db?zeroDateTimeBehavior=convertToNull"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="javax.persistence.schema-generation.database.action" value="none"/>
<!--<property name="hibernate.show_sql" value="true"/>-->
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
Person:
package com.gmail.physicistsarah.gradletestproject.core;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
*
* #author Sarah Szabo
*/
#Entity
#Table(name = "Person")
public class Person {
#Id
#GeneratedValue
#Column(name = "Person_ID")
private final int id = 0;
#Column(name = "First_Name", nullable = false)
private final String firstName;
#Column(name = "Last_Name", nullable = false)
private final String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
Init (Main class):
package com.gmail.physicistsarah.gradletestproject.core;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class Init {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("Test_Project");
EntityManager manager = factory.createEntityManager();
Session session = manager.unwrap(Session.class);
Transaction transaction = session.getTransaction();
transaction.begin();
session.saveOrUpdate(new Person("Carl", "Gauss"));
session.saveOrUpdate(new Person("Benoit", "Mandelbrot"));
transaction.commit();
factory.close();
}
}
You should try using HibernatePersistenceProvider and remove the <class> element from the persistence.xml.
Also remove <exclude-unlisted-classes> since it is not applicable to Java SE persistence units as per the official schema definition http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_1.xsd
<?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="Test_Project" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<shared-cache-mode>ALL</shared-cache-mode>
<validation-mode>AUTO</validation-mode>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test_project_db?zeroDateTimeBehavior=convertToNull" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
</persistence>
I noticed that you are inter mixing JPA code with Hibernate code. If you're using JPA then try to stick to JPA.
Use the following code after creating the EntityManager:
EntityTransaction tran = manager.getTransaction();
tran.begin();
try {
Person savedPerson1 = manager.merge(new Person("Carl", "Gauss"));
Person savedPerson2 = manager.merge(new Person("Benoit", "Mandelbrot"));
tran.commit();
} catch (Exception e) {
tran.rollback();
}
manager.close();
factory.close();
Remember to access the returned entity from EntityManager.merge() call to access any auto-generated fields.
You should use the following Maven POM dependencies for the above to work as expected in a Java SE environment:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.8.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

Hibernate Mapping JPA Collections

I want to do a pretty simple thing but can't get it to work.
I have ab entity Game and an Entity Player. Every Game should have two foreign keys from Players. And it works, but there is one catch: I cant assign the same foreign key from Player to multiple Game-entities. Where is this constraint coming from, and how can I tell him to not do that?
I'm using Hibernate and JPA. My persistence.xml looks like this:
<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" version="1.0">
<persistence-unit name="PlayerService" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.connection.username" value="********"/>
<property name="hibernate.connection.password" value="********"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://********"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
I'm getting the entitymanager per:
util = new JPAUtil();
emf = Persistence.createEntityManagerFactory("PlayerService");
em = emf.createEntityManager();
em.getTransaction().begin();
in my Games-Entity:
#ElementCollection(targetClass=Player.class)
private Collection<Player> player;
and there is Player-Entity.
Am I doing this entirely wrong?
#Entity
public class Game {
#Id
int gameid;
#OneToMany(mappedBy="game")
private Collection<TestPlayer> test;
}
#Entity
public class TestPlayer {
#Id
int id;
#ManyToOne
#JoinColumn(name="gameid")
private Game game;
}
I'll try an OneToMany relationship instead of ElementCollection.
I think that in an ElementCollection the elements (Player) belongs to the Game and therefore Hibernate doesn't let you assign it to multiple Games
in your Game Entity:
#OneToMany(mappedBy="game")
private Collection<Player> player;
in your Player entity:
#ManyToOne
#JoinColumn(name="game_id")
private Game game;
for reference: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association

Categories