org.hibernate.ResourceClosedException - java

i am getting this error when I want to run the following code:
package HIndexSaar.HIndex;
public class AppHibernate {
public static void main(String[] args){
HibernateManager mng = new HibernateManager();
mng.addPerson("H H", "Uni Saarland");
mng.addPerson("Bernd Finkbeiner", "Uni Saarland");
mng.addUniversity("Saarland University");
}
}
My HibernateManager class:
package HIndexSaar.HIndex;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateManager {
private static SessionFactory ourSessionFactory;
private static ServiceRegistry serviceRegistry;
public HibernateManager(){
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
ourSessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
/**
* adds a person to the database.
* #param name: the name of the person
* #param affiliation: the university of the person
* #return the created ID
*/
public Integer addPerson(String name, String affiliation){
Transaction tx = null;
Integer personID = null;
try (Session session = ourSessionFactory.openSession()) {
tx = session.beginTransaction();
Person p = new Person(name, affiliation);
personID = (Integer) session.save(p);
tx.commit();
} catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
}
return personID;
}
/**
* adds a university to the database.
* #param name: the name of the university
* #return the id of the newly created university
* */
public Integer addUniversity(String name){
Transaction trans = null;
Integer uniID = null;
try (Session session = ourSessionFactory.openSession()) {
trans = session.beginTransaction();
University uni = new University(name);
uniID = (Integer) session.save(uni);
trans.commit();
} catch (HibernateException e) {
if (trans != null) {
trans.rollback();
}
e.printStackTrace();
}
return uniID;
}
/**
* adds a publication to the database.
* #param name: the name of the publication
* #param author: the author of the publication
* #return the generated ID
*/
public Integer addPublication(String name, String author){
Transaction trans = null;
Integer pubID = null;
try (Session session = ourSessionFactory.openSession()) {
trans = session.beginTransaction();
Publication p = new Publication(name, author);
pubID = (Integer) session.save(p);
trans.commit();
} catch (HibernateException e) {
if (trans != null) {
trans.rollback();
}
e.printStackTrace();
}
return pubID;
}
}
And my hibernate.cfg.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="HIndex Session">
<!-- Database connection settings -->
<property name="connection.driver:class">org.postgreSQL.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost/HIndex</property>
<property name="hibernate.connection.username">index_user</property>
<property name="hibernate.connection.password">password</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL Dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</property>
<!-- Assume test is the database name -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<!-- Names the annotated entity class -->
<mapping class="HIndexSaar.HIndex.Person"/>
<mapping class="HIndexSaar.HIndex.University"/>
<mapping class="HIndexSaar.HIndex.Publication"/>
</session-factory>
</hibernate-configuration>
And the pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>HIndexSaar</groupId>
<artifactId>HIndex</artifactId>
<version>Version 0.2</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<packaging>jar</packaging>
<name>HIndex</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<!-- jsoup HTML parser library # http://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1207</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.5.6-Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.0-RC1</version>
</dependency>
</dependencies>
</project>
The error is shown at the "tx.rollback();" line:
catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
}
I do not use multiple threads anywhere, so what am I missing?

From the docs for ResourceClosedException:
Indicates an attempt was made to use a closed resource (Session,
SessionFactory, etc).
Now, when using "try with resources", the documentation says:
Note: A try-with-resources statement can have catch and finally blocks
just like an ordinary try statement. In a try-with-resources
statement, any catch or finally block is run after the resources
declared have been closed.
So by the time you call rollback() the Session will already have been closed.
The simplest solution here would be to move your existing catch block to an inner try/catch block around the transaction-management code, e.g.:
try (Session session = ourSessionFactory.openSession()) {
try {
tx = session.beginTransaction();
Person p = new Person(name, affiliation);
personID = (Integer) session.save(p);
tx.commit();
}
catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
}
}
This ensures that the Session only gets closed once you've (at least) requested rollback.

Related

JPA - EntityListener - #PrePersist and #PreUpdate work successfully, but #PostPersist and #PostUpdate not working

Possible Duplicated
I have this weird bug in my Java Desktop Application, when i use #PrePersist and #PreUpdate all the code from the callback methods is executed, but when i use #PostPersist and #PostUpdate only the System.out.println(...) code is executed.
Here's my code:
Entity -> Area
import com.pete.bibliogere.modelo.listeners.EntidadeOperacoes;
import com.pete.bibliogere.modelo.listeners.EntidadeOperacoesInterface;
#Entity
#Table(name = "areas")
#EntityListeners(value = EntidadeOperacoes.class)
public class Area implements Serializable, EntidadeOperacoesInterface {
#Column(updatable = false, name = "data_registo")
private LocalDate dataRegisto;
#Column(name = "data_alteracao")
private LocalDate dataAlteracao;
... Some Getters, Setters and other attributes omited...
#Override
public void setDataRegisto(LocalDate data_registo) {
this.data_registo = data_registo;
}
#Override
public void setDataAlteracao(LocalDate data_alteracao) {
this.data_alteracao = data_alteracao;
}
}
Interface for Entities to share the same external EntityListener
public interface EntidadeOperacoesInterface {
public void setDataRegisto(LocalDate data_registo);
public void setDataAlteracao(LocalDate data_alteracao);
}
External EntityListener -> EntidadeOperacoes
public class EntidadeOperacoes {
#PostPersist
public void antesRegistar(EntidadeOperacoesInterface entidade) {
System.out.println("-------- Inserindo data Inserção ------");
entidade.setDataRegisto(LocalDate.now());
System.out.println("-------- Fim Inserção ------");
}
#PostUpdate
public void depoisAlteracao(EntidadeOperacoesInterface entidade) {
System.out.println("-------- Data Atualização ------");
entidade.setDataAlteracao(LocalDate.now());
System.out.println("-------- Fim ------");
}
AreaController
public final class AreaController {
private EntityManager em;
private Validator validator;
private AreaDao dao;
public void registar(String nome, String localizacao) {
validator = ValidatorUtil.getValidator();
em = JpaUtil.getEntityManager();
em.getTransaction().begin();
dao = new AreaServico(em, validator);
dao.registar(new Area(nome.trim(), localizacao.trim()));
em.getTransaction().commit();
em.close();
ValidatorUtil.close();
}
public void alterar(long codigo, String nome, String localizacao) {
validator = ValidatorUtil.getValidator();
em = JpaUtil.getEntityManager();
em.getTransaction().begin();
dao = new AreaServico(em, validator);
dao.atualizar(new Area(codigo, nome, localizacao));
em.getTransaction().commit();
em.close();
ValidatorUtil.close();
}
// Testing Purposes
public static void main(String[] args) {
AreaController ac = new AreaController();
// Persiste area
ac.registar("Area 1", "Localização 1");
}
*AreaServico -> Service Class
public class AreaServico implements AreaDao {
private EntityManager em;
private Validator validator;
public AreaServico(EntityManager em, Validator validator) {
this.em = em;
this.validator = validator;
}
#Override
public void registar(Area area) {
Set<ConstraintViolation<Area>> constraintViolations = validator.validate(area);
if (constraintViolations.iterator().hasNext()) {
JOptionPane.showMessageDialog(null, constraintViolations.iterator().next().getMessage(), "Atenção!", JOptionPane.ERROR_MESSAGE);
} else {
if (areaExiste(area.getNome())) {
JOptionPane.showMessageDialog(null, "Erro: A área digitada já existe."
+ "\nCertifique-se de escolher outro nome!", "Area existente!", JOptionPane.ERROR_MESSAGE);
} else {
em.persist(area);
}
}
}
#Override
public void atualizar(Area area) {
Area areaEncontrada = em.find(Area.class, area.getCodigo());
Set<ConstraintViolation<Area>> constraintViolations = validator.validate(area);
if (areaEncontrada != null) {
if (constraintViolations.iterator().hasNext()) {
JOptionPane.showMessageDialog(null, "Erro: " + constraintViolations.iterator().next().getMessage());
} else {
if (areaExiste(area.getCodigo(), area.getNome())) {
JOptionPane.showMessageDialog(null, "Erro: Já existe uma área com este nome.\n"
+ "Certifique-se de escolher um nome diferente!", "Area existente!", JOptionPane.ERROR_MESSAGE);
} else {
areaEncontrada.setNome(area.getNome());
areaEncontrada.setLocalizacao(area.getLocalizacao());
}
}
} else {
JOptionPane.showMessageDialog(null, "Erro: A área digitada não existe!");
}
}
Here's the console log when i execute the Main method above
Handling #sessionFactoryCreated from [org.hibernate.internal.SessionFactoryImpl#37b52340] for TypeConfiguration
select
area0_.codigo as codigo1_0_,
area0_.data_alteracao as data_alt2_0_,
area0_.data_registo as data_reg3_0_,
area0_.localizacao as localiza4_0_,
area0_.nome as nome5_0_
from
areas area0_
where
upper(area0_.nome)=?
binding parameter [1] as [VARCHAR] - [AREA 1]
insert
into
areas
(data_alteracao, data_registo, localizacao, nome)
values
(?, ?, ?, ?)
binding parameter [1] as [DATE] - [null]
binding parameter [2] as [DATE] - [null] /* This shouldn't be null, but LocalDate.now() */
binding parameter [3] as [VARCHAR] - [Localização 1]
binding parameter [4] as [VARCHAR] - [Area 1]
Depois de Inserir registo - Inicio: 1934663431---
Depois de Inserir registo - Fim:1934663440---
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 6.344 s
Finished at: 2020-10-29T09:44:24+02:00
Here's my POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pete</groupId>
<artifactId>BiblioGere</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-agroal</artifactId>
<version>5.4.22.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-osgi-karaf-features</artifactId>
<version>6.1.6.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-cdi</artifactId>
<version>6.1.6.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.18</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.4.22.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.15.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
</dependencies>
</project>
You set updatable = false on dataRegisto field so it seems normal the setter doesn't update the value in database.
#PostUpdate is called after fulshing the session.
Could you try to add :
#Autowired
private EntityManager entityManager;
And after calling update :
entityManager.flush();
Best regards.

"Exception in thread "mainHow to resolve this exception: " java.lang.NoClassDefFoundError: net/bytebuddy/NamingStrategy..."

I'm trying to connect a local database to my application using hibernate. I'm getting the following error:
Jul 02, 2019 9:20:08 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {[WORKING]}
Exception in thread "main" java.lang.NoClassDefFoundError: net/bytebuddy/NamingStrategy$SuffixingRandom$BaseNameResolver
at org.hibernate.orm.core#5.4.3.Final/org.hibernate.cfg.Environment.buildBytecodeProvider(Environment.java:345)
at org.hibernate.orm.core#5.4.3.Final/org.hibernate.cfg.Environment.buildBytecodeProvider(Environment.java:337)
at org.hibernate.orm.core#5.4.3.Final/org.hibernate.cfg.Environment.<clinit>(Environment.java:230)
at org.hibernate.orm.core#5.4.3.Final/org.hibernate.boot.registry.StandardServiceRegistryBuilder.<init>(StandardServiceRegistryBuilder.java:78)
at org.hibernate.orm.core#5.4.3.Final/org.hibernate.boot.registry.StandardServiceRegistryBuilder.<init>(StandardServiceRegistryBuilder.java:67)
at org.hibernate.orm.core#5.4.3.Final/org.hibernate.boot.registry.StandardServiceRegistryBuilder.<init>(StandardServiceRegistryBuilder.java:58)
at ProjectDBTest/ProjectDBTest2.HibernateUtil.getSessionFactory(HibernateUtil.java:28)
at ProjectDBTest/ProjectDBTest2.App.main(App.java:28)
Caused by: java.lang.ClassNotFoundException: net.bytebuddy.NamingStrategy$SuffixingRandom$BaseNameResolver
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 8 more
Any help on how to resolve this would be greatly appreciated.
Initially, I was getting 'java.lang.NoClassDefFoundError: java/sql/SQLException' exception and so I added 'requires java.sql' after seeing this as a suggested solution elsewhere on Stack Overflow, but now a the exception described above arises. I'm not sure where I'm gone wrong in my code or what is missing.
Here is my module-info.java file:
module ProjectDBTest {
requires java.persistence;
//requires lombok;
requires javafx.graphics;
requires org.hibernate.orm.core;
requires java.naming;
requires java.sql;
exports ProjectDBTest2.DB;
}
main class:
package ProjectDBTest2;
import ProjectDBTest2.DB.Vocabulary;
import org.hibernate.Session;
import org.hibernate.Transaction;
import java.util.List;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
Vocabulary word1 = new Vocabulary();
word1.setUnitID(1);
word1.setWord("test");
word1.setVocabClass("noun");
word1.setVocabDefinition("this is a test");
word1.setVocabID(7);
System.out.println(word1.getUnitID());
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
session.save(word1);
transaction.commit();
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
}
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
List< Vocabulary > students = session.createQuery("from Vocabulary ", Vocabulary.class).list();
students.forEach(s -> System.out.println(s.getWord()));
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
}
}
}
Hibernate util file:
package ProjectDBTest2;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class HibernateUtil {
private static StandardServiceRegistry registry;
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
// Create registry
registry = new StandardServiceRegistryBuilder().configure().build();
// Create MetadataSources
MetadataSources sources = new MetadataSources(registry);
// Create Metadata
Metadata metadata = sources.getMetadataBuilder().build();
// Create SessionFactory
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Exception e) {
e.printStackTrace();
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
return sessionFactory;
}
public static void shutdown() {
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
Persistence data class:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
//#Data
#Entity
#Table(name = "vocabulary")
public class Vocabulary {
#Id
#Column(name = "V_ID")
private int vocabID;
#Column(name = "V_WORD")
private String word;
#Column(name = "V_CLASS")
private String vocabClass;
#Column(name = "V_DEFINITION")
private String vocabDefinition;
#Column(name = "U_ID")
private int unitID;
public int getVocabID() {
return vocabID;
}
public void setVocabID(int vocabID) {
this.vocabID = vocabID;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public String getVocabClass() {
return vocabClass;
}
public void setVocabClass(String vocabClass) {
this.vocabClass = vocabClass;
}
public String getVocabDefinition() {
return vocabDefinition;
}
public void setVocabDefinition(String vocabDefinition) {
this.vocabDefinition = vocabDefinition;
}
public int getUnitID() {
return unitID;
}
public void setUnitID(int unitID) {
this.unitID = unitID;
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ProjectDBTest2</groupId>
<artifactId>ProjectDBTest2.0</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ProjectDBTest2.0</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy -->
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.3.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok-->
<!--
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency> -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.0.Final</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>13-ea+9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.openjfx/javafx -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>13-ea+9</version>
<type>pom</type>
</dependency>
<!-- https://mvnrepository.com/artifact/org.openjfx/javafx-base -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>13-ea+9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.openjfx/javafx-controls -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>13-ea+9</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
I'm using intelliJ ultimate 2019.1 and language level is set to 11.
I finally managed to solve the issue by updating my module-info.java file to include:
module AlienDB {
requires static lombok;
requires java.persistence;
requires org.hibernate.orm.core;
requires java.naming;
requires java.sql;
requires com.sun.xml.bind;
requires net.bytebuddy;
opens Aliens to org.hibernate.orm.core;
exports Aliens;
}
Previously I was adding java.xml.bind which was causing further issues.

Hibernate 5.2.17 not rolling back failed transactions

I'm currently in the process of updating a large project from Hibernate 5.1 to Hibernate 5.2.17 and I'm running into an issue that I'm struggling to resolve.
We have a suite of tests that are testing our DAOs using the H2 in-memory database, but some tests have started to fail on the updated version of Hibernate.
Some of the tests attempt to delete a null entity from the persistence context and expect the operation to fail with an IllegalArgumentException. With the new version of Hibernate the exception is still thrown as expected, but the transaction is no longer being rolled back and is being left active, and is consequently causing subsequent tests to fail because there's already an active transaction. Stack trace included below:
java.lang.AssertionError: Transaction is still active when it should have been rolled back.
at org.junit.Assert.fail(Assert.java:88)
at hibernatetest.persistence.HibernateTestDAOTest.testDeleteDetachedEntity(HibernateTestDAOTest.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
While investigating I noticed a similar difference in behaviour when attempting to delete a detached entity as well. I have been able to recreate the behaviour in a small, standalone project that can be found here. The project also includes configuration in the pom.xml (commented out) for running against Hibernate 5.0.10, where the tests pass with no issue and the failed transaction is correctly rolled-back.
While I haven't been able to recreate the error deleting a null entity, I have managed to recreate it with a detached entity, and I'm hoping the answer to why this is happening will help guide me to why it's also failing with null in the real code.
Are we doing something wrong here, or is this an issue with Hibernate itself?
Code also included below:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>HibernateTest</groupId>
<artifactId>HibernateTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.version>3.7.0</maven.compiler.version>
<!-- Uncomment this property to run as Hibernate 5.0.10 -->
<!-- <hibernate.core.version>5.0.10.Final</hibernate.core.version> -->
<!-- Uncomment this property to run as Hibernate 5.2.17 -->
<hibernate.core.version>5.2.17.Final</hibernate.core.version>
<junit.version>4.12</junit.version>
<h2.version>1.4.197</h2.version>
<javaee.api.version>7.0</javaee.api.version>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.core.version}</version>
</dependency>
<!-- Uncomment these dependencies to run using Hibernate 5.0.10 -->
<!--
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-java8</artifactId>
<version>${hibernate.core.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.core.version}</version>
<scope>test</scope>
</dependency>
-->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee.api.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
HibernateTest.java (entity class):
package hibernatetest.persistence;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
#Entity
#Table(name = "hibernate_test")
public class HibernateTest {
#Id
#Column(name = "id")
#Type(type = "uuid-char")
private UUID id;
public HibernateTest(final UUID id) {
this.id = id;
}
}
HibernateTestDAO.java
package hibernatetest.persistence;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
public class HibernateTestDAO {
#PersistenceContext(unitName = "hibernate-test")
private EntityManager entityManager;
public void delete(final HibernateTest entity) {
entityManager.remove(entity);
}
}
EntityManagerRule.java (JUnit Rule to provide the entity manager for the tests):
package hibernatetest.persistence;
import java.lang.reflect.Field;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.junit.rules.ExternalResource;
public class EntityManagerRule extends ExternalResource {
private EntityManagerFactory emFactory;
private EntityManager em;
#Override
protected void before() {
emFactory = Persistence.createEntityManagerFactory("hibernate-test");
em = emFactory.createEntityManager();
}
#Override
protected void after() {
if (em != null) {
em.close();
}
if (emFactory != null) {
emFactory.close();
}
}
public HibernateTestDAO initDAO() {
final HibernateTestDAO dao = new HibernateTestDAO();
try {
injectEntityManager(dao);
} catch (Exception e) {
e.printStackTrace();
}
return dao;
}
public EntityManager getEntityManager() {
return em;
}
public void persist(final Object entity) {
final EntityTransaction transaction = em.getTransaction();
transaction.begin();
try {
em.persist(entity);
} catch (Exception e) {
transaction.rollback();
throw e;
}
transaction.commit();
}
private void injectEntityManager(final HibernateTestDAO dao) throws Exception {
final Field emField = dao.getClass().getDeclaredField("entityManager");
emField.setAccessible(true);
emField.set(dao, em);
}
}
HibernateTestDAOTest.java:
package hibernatetest.persistence;
import static org.junit.Assert.fail;
import java.util.UUID;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class HibernateTestDAOTest {
#Rule
public EntityManagerRule rule = new EntityManagerRule();
private HibernateTestDAO dao;
#Before
public void setup() {
dao = rule.initDAO();
}
#Test
public void testDeleteNullEntity() {
HibernateTest entity = null;
try {
dao.delete(entity);
} catch (IllegalArgumentException e) {
if (rule.getEntityManager().getTransaction().isActive()) {
fail("Transaction is still active when it should have been rolled back.");
}
}
}
#Test
public void testDeleteDetachedEntity() {
HibernateTest entity = new HibernateTest(UUID.randomUUID());
rule.persist(entity);
rule.getEntityManager().detach(entity);
try {
dao.delete(entity);
} catch (IllegalArgumentException e) {
if (rule.getEntityManager().getTransaction().isActive()) {
fail("Transaction is still active when it should have been rolled back.");
}
}
}
}
persistence.xml from src/test/resources/META-INF:
<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="hibernate-test" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>hibernatetest.persistence.HibernateTest</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:h2:mem:test;INIT=create schema if not exists test\;runscript from 'classpath:/populate.sql';DB_CLOSE_DELAY=-1;"/>
<property name="javax.persistence.validation.mode" value="none"/>
</properties>
</persistence-unit>
</persistence>
populate.sql from src/test/resources:
CREATE TABLE IF NOT EXISTS hibernate_test (
id UUID NOT NULL
);
Nothing in the spec states that when a call to EntityManager#remove fails that the persistence provider should rollback the existing transaction, that just makes no sense.
If you look at all the examples in the Hibernate test suite, you'll notice this behavior:
EntityManager entityManager = getOrCreateEntityManager();
try {
entityManager.getTransaction().begin();
// do something
entityManager.getTransaction().commit();
}
catch ( Exception e ) {
if ( entityManager != null && entityManager.getTransaction.isActive() ) {
entityManager.getTransaction().rollback();
}
throw e;
}
finally {
if ( entityManager != null ) {
entityManager.close();
}
}
If your tests worked previously and no longer do in the same way, I'm not sure I'd necesssarily say that is a bug as the code which you've supplied above does not conform to what I have shown here with properly handling the rollback in user code unless you have spring or some other framework at play which you haven't illustrated.
But if you feel there is a regression between 5.1 and 5.2, you're welcomed to open a JIRA and report it with your reproducable test use case and we can do further investigation.
One key point to remember is that 5.2.x introduced the merging of the JPA artifact hibernate-entitymanager into hibernate-core proper, so there could be a regression here with that but its extremely unlikely.

Transaction rollback in JPA never works

I have a piece of example code:
public class JpaTest {
private EntityManagerFactory emf;
private void setUp() throws Exception {
emf = Persistence.createEntityManagerFactory("testPU");
}
private void tearDown() {
emf.close();
}
private void save() {
EntityManager em = null;
EntityTransaction tx = null;
try {
em = emf.createEntityManager();
tx = em.getTransaction();
tx.begin();
em.persist(new Event("First event", new Date()));
em.persist(new Event("A follow up event", new Date()));
throw new RuntimeException();
} catch (Exception e) {
if (tx != null) tx.rollback();
} finally {
if (em != null) em.close();
}
}
public static void main(String[] args) throws Exception {
JpaTest test = new JpaTest();
test.setUp();
test.save();
test.tearDown();
}
}
The database is MySQL.
The code persists Event entity into the database and than throws an Exception. I expect tx.rollback() to delete the changes made into the database, but this command never works and the data remains in the table:
The question is why tx.rollback() fails and how to delete changes made in the database if transaction throws an Exception?
UPDATED:
persistence.xml:
<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="testPU">
<class>exampleForTestingJpa.Event</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url"
value="url here..."/>
<property name="javax.persistence.jdbc.user" value="username here..."/>
<property name="javax.persistence.jdbc.password" value="password here..."/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.connection.autocommit" value="false"/>
</properties>
</persistence-unit>
</persistence>
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>example</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.9.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
</dependencies>
</project>
Add this to your persistence.xml
<property name="hibernate.connection.autocommit" value="false"/>
Maybe autocommit is enabled ? MySQL manual states that autocommit is enabled by default.
If thats the problem, you surely will not be the first who stumbled over that ;-)
As other users said, it is probably a auto-commit issue since according to the MySQL documentation :
In InnoDB ...
By default, MySQL starts the session for each new connection with
autocommit enabled, so MySQL does a commit after each SQL statement if
that statement did not return an error. If a statement returns an
error, the commit or rollback behavior depends on the error. See
Section 14.21.4, “InnoDB Error Handling”.
Besides, you should not store the Transaction object in a variable.
At each time you want to invoke a Transaction method, get the Transaction object from the EntityManager.
So replace :
tx = em.getTransaction();
tx.begin();
by :
em.getTransaction().begin();
And replace tx.rollback(); by em.getTransaction().rollback();
The Transaction object stored in the EntityManager may be serialized and so have a new reference during transaction processing.
For example, look at the serialization method of AbstractEntityManagerImpl:
public class org.hibernate.jpa.spi.AbstractEntityManagerImpl{
...
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
tx = new TransactionImpl( this );
}
...
}
The problem with not rolling transaction back was caused by MyISAM. With InnoDB rollback works fine.

Querydsl - Exception in thread "main" java.lang.IllegalArgumentException: No sources given

I'm building a system using Spring MVC, Thymeleaf, JPA (Hibernate), and Querydsl. While I was testing everything, I came across this exception:
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Serviço nulo: false
[SER_USU] - Fazendo consulta...
[SER_USU] - Dao nulo: false
Exception in thread "main" java.lang.IllegalArgumentException: No sources given
at com.querydsl.jpa.JPAQueryBase.serialize(JPAQueryBase.java:56)
at com.querydsl.jpa.JPAQueryBase.serialize(JPAQueryBase.java:50)
at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:98)
at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:94)
at com.querydsl.jpa.impl.AbstractJPAQuery.fetch(AbstractJPAQuery.java:201)
at com.regra7.st.db.dao.Dao_Usuario.getPorID(Dao_Usuario.java:35)
at com.regra7.st.servico.Ser_Usuario.cadastrar(Ser_Usuario.java:46)
at com.regra7.st.testes.TesteDAO_001.<init>(TesteDAO_001.java:43)
at com.regra7.st.testes.TesteDAO_001.main(TesteDAO_001.java:19)
Unfortunately, this is not very descriptive, and so, I do not know what to do. I've tried everything, but I do not find the solution. And yes, thats all the message (the stacktrace). Here are some files I'm using...
pom.xml (I may have some dependencies wrong, I don't know exactly):
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.regra7</groupId>
<artifactId>Sistema_Teste_001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<!-- QUERYDSL -->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<!-- SPRING MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<!-- SPRING CONTEXT (SPRING CORE - TRANSIENT) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<!-- POSTGRESQL DRIVER JDBC -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
<!-- API SERVLET E JSP -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- BEAN VALIDATION -->
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.6.Final</version>
</dependency>
<!-- IMPLEMENTAÇÃO BEAN VALIDATION (HIBERNATE) -->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.4.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.1-api -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<!-- THYMELEAF -->
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>
<!-- THYMELEAF PARA O SPRING 4 -->
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.querydsl/querydsl-core -->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>4.1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.querydsl/querydsl-jpa -->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>4.1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.querydsl/querydsl-apt -->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>4.1.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<!-- C3P0 -->
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
</dependencies>
</project>
spring-config.xml (app-context.xml):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- ARQUIVO DE CONFIGURAÇÃO DE CONTEXTO DE APLICAÇÃO. -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd ">
<!-- Mapeamento de recursos (arquivos css, fontes, imagens, dentre outros). -->
<!-- <mvc:resources mapping="/css/**" location="/WEB-INF/recursos/css/" /> -->
<!-- <mvc:resources mapping="/imagens/**" location="/WEB-INF/recursos/imagens/" /> -->
<!-- <mvc:resources mapping="/fontes/**" location="/WEB-INF/recursos/fontes/" /> -->
<!-- <mvc:resources mapping="/fontes/**" location="/WEB-INF/recursos/javascript/" /> -->
<!-- Possibilita o uso de anotações Spring Mvc. -->
<mvc:annotation-driven />
<!-- Alternativa a declarar PersistenceAnnotationBeanPostProcessor,
um processador de anotações que lê #PersistenceContext. -->
<context:annotation-config />
<!-- Define local para procura de componentes Spring (beans configurados
por anotações em classes). -->
<context:component-scan base-package="com.regra7.st.controle" />
<context:component-scan base-package="com.regra7.st.db.dao" />
<context:component-scan base-package="com.regra7.st.servico" />
<context:component-scan base-package="com.regra7.st.testes" />
<!-- MINHA DEFINIÇÃO COM MEUS CONVERSORES CRIADOS -->
<mvc:annotation-driven conversion-service="servicoConversao"/>
<!-- PROPERTY EDITOR NÃO FUNCIONOU, MAS ISSO SIM! -->
<bean id="servicoConversao"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.regra7.st.formularios.conversores.Cov_String_LocalDate"/>
<bean class="com.regra7.st.formularios.conversores.Cov_LocalDate_String"/>
</set>
</property>
</bean>
<!-- Template Resolver para Template Engine. -->
<!-- <bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/" /> <property name="suffix"
value=".html" /> <property name="templateMode" value="HTML5" /> </bean> -->
<!-- SpringResourceTemplateResolver automatically integrates with Spring's
own -->
<!-- resource resolution infrastructure, which is highly recommended. -->
<bean id="templateResolver"
class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/" />
<property name="suffix" value=".html" />
<!-- HTML is the default value, added here for the sake of clarity. -->
<property name="templateMode" value="HTML" />
<!-- Template cache is true by default. Set to false if you want -->
<!-- templates to be automatically updated when modified. -->
<property name="cacheable" value="true" />
</bean>
<!-- SpringTemplateEngine automatically applies SpringStandardDialect and -->
<!-- enables Spring's own MessageSource message resolution mechanisms. -->
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<!-- Enabling the SpringEL compiler with Spring 4.2.4 or newer can speed
up -->
<!-- execution in most scenarios, but might be incompatible with specific -->
<!-- cases when expressions in one template are reused across different
data -->
<!-- ypes, so this flag is "false" by default for safer backwards -->
<!-- compatibility. -->
<property name="enableSpringELCompiler" value="true" />
</bean>
<!-- View resolver do Thymeleaf. -->
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
</bean>
<!-- DATA SOURCE - Implementação do C3p0 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<!-- Propriedades de conexão -->
<property name = "driverClass" value="org.postgresql.Driver" />
<property name = "jdbcUrl" value="jdbc:postgresql://localhost:5432/SistemaTeste" />
<property name = "user" value="postgres" />
<property name = "password" value="admin" />
<!-- Propriedades C3p0 -->
<property name = "initialPoolSize" value="3" />
<property name = "minPoolSize" value="5" />
<property name = "maxPoolSize" value="20" />
<property name = "maxIdleTime" value="1800" /> <!-- 1800 = 30 min -->
<property name = "maxStatements" value="50" />
</bean>
<!-- Fábrica EntityManager -->
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="SistemaTeste" />
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">none</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.use_sql_comments">false</prop>
<prop key="hibernate.default_schema">regrast</prop>
<prop key="hibernate.jdbc.batch_size">50</prop>
</props>
</property>
</bean>
<!-- Gerenciador de transações PlatformTransactionManager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<!-- INTERCEPTADORES -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/usuario/*" />
<bean class="com.regra7.st.interceptadores.Login" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
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="SistemaTeste" transaction-type="RESOURCE_LOCAL">
<!-- PROVEDOR JPA -->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
</persistence-unit>
</persistence>
My main test class:
public class TesteDAO_001
{
public static void main(String[] args)
{
new TesteDAO_001(); // Line 19
}
public TesteDAO_001()
{
AbstractApplicationContext ac = new ClassPathXmlApplicationContext("/META-INF/spring-config.xml");
Ser_Usuario servico = ac.getBean(Ser_Usuario.class); // Service class
// For_Cadastro is an account registration form.
For_Cadastro form = new For_Cadastro();
form.setNome("Maria Pereira Maxwell"); // Name
form.setLogin("rodrigologinsoares001");
form.setSenha1("minhasenha001001"); // Password
form.setSenha2("minhasenha001001"); // Password confirmation
form.setCpf("01234567890"); // CPF = Brazil's Social ID
form.setNascimento(LocalDate.now()); // Birthday
form.setPai(0L); // Father
form.setMae(0L); // Mother
form.setGenero(0L); // Gender
System.out.printf("Serviço nulo: %s%n" , servico == null);
servico.cadastrar(form); // Line 43
ac.close();
}
}
Service method:
#Autowired
private Dao_Usuario _daoUsu;
#Transactional(rollbackFor = Exception.class)
public void cadastrar(For_Cadastro form)
{
imprimir("Fazendo consulta...");
imprimir(String.format("Dao nulo: %s%n", this._daoUsu == null));
// This may return null.
Usuario pai = this._daoUsu.getPorID(form.getPai()); // Line 46
Usuario mae = this._daoUsu.getPorID(form.getMae());
imprimir(String.format("pai nulo: %s%n", pai == null));
imprimir(String.format("mea nulo: %s%n", mae == null));
// Usuario is a Domain Model Object. A POJO representation of a table.
Usuario usu = new Usuario(form.getCpf()); // CPF = Brazil's Social ID
usu.setGenero(Genero.getGenero(form.getGenero())); // Gender
usu.setNome(form.getNome()); // Name
usu.setLogin(form.getLogin());
usu.setSenha(form.getSenha1().getBytes()); // Password
usu.setNascimento(form.getNascimento()); // Birthday
usu.setMae(mae); // Mother
usu.setPai(pai); // Father
imprimir("Modelo criado. Salvando...");
this._daoUsu.salvarAtualizar(usu); // Save/Update
imprimir("Persistência concluída.");
}
DAO method:
#PersistenceContext
protected EntityManager _em;
#Override
public Usuario getPorID(Long id)
{
if(id == null)
{
return null;
}
return new JPAQueryFactory(this._em)
.select(QUsuario.usuario)
.where(QUsuario.usuario.id.eq(id))
.fetchOne(); // Line 32
}
I'm learning how to use Querydsl. If you need me to add any more code here, please say so. I already researched google, and also here in the community. Unfortunately I did not find anything about it. Can somebody help me, please?
Thank you for your time and patience.
EDIT
Here's my Domain Model Usuario Class:
#Entity
#Table(name="tb_usuarios")
public class Usuario
{
#Id
#SequenceGenerator(
name="ger_id_usuario" ,
sequenceName="tb_usuarios_id_seq" ,
allocationSize=1 ,
initialValue = 1)
#GeneratedValue(
strategy=GenerationType.SEQUENCE ,
generator="ger_id_usuario")
#Column(
name = "usu_id" ,
unique = true)
protected Long id;
// Name
#Column(name = "usu_nome" , unique = true)
protected String nome;
// "Business Key"
#Column(name = "usu_login" , unique = true)
protected String login;
// Password
#Column(name = "usu_senha" , unique = true)
protected byte[] senha;
// Brazil's Social ID
// "Business Key"
#Column(name = "usu_cpf" , unique = true)
protected String cpf;
// Registration moment (date and time)
#Column(name = "usu_nascimento")
protected Date nascimento;
// Gender
#Column(name = "usu_genero")
protected byte genero;
// Father of this person (it may be null).
#ManyToOne(fetch = FetchType.LAZY , cascade=CascadeType.ALL)
#JoinColumn(name = "usu_pai")
protected Usuario pai;
// Mother of this person (it may be null).
#ManyToOne(fetch = FetchType.LAZY , cascade=CascadeType.ALL)
#JoinColumn(name = "usu_mae")
protected Usuario mae;
#Column(name = "usu_cadastro")
protected Timestamp cadastro;
// Children as a father.
#OneToMany(mappedBy="pai" , fetch = FetchType.LAZY , cascade = CascadeType.ALL)
protected Set<Usuario> filhosComoPai;
// Children as a mother.
#OneToMany(mappedBy="mae" , fetch = FetchType.LAZY , cascade = CascadeType.ALL)
protected Set<Usuario> filhosComoMae;
// Required by default by JPA, public or protected constructor, with no arguments.
protected Usuario()
{
this.filhosComoPai = new HashSet<>();
this.filhosComoMae = new HashSet<>();
}
/** For anyone who works with this class, it must provide a CPF, guaranteeing uniqueness, thus preventing this class from suffering problems when it is inside collections. */
public Usuario(String cpf)
{
if(Util_Validador.isCPFValido(cpf) == false)
{
throw new IllegalArgumentException("CPF não encontra-se válido.");
}
this.cpf = cpf;
this.filhosComoPai = new HashSet<>();
this.filhosComoMae = new HashSet<>();
}
// Name
public void setNome(String nome)
{
if(Util_Validador.isNomeValido(nome, 8) == false)
{
throw new IllegalArgumentException("Nome de pessoa não encontra-se válido.");
}
this.nome = nome;
}
public void setLogin(String login)
{
if(Util_Validador.isLoginValido(login, 8) == false)
{
throw new IllegalArgumentException("Login não encontra-se válido.");
}
this.login = login;
}
// Password
public void setSenha(byte[] senha)
{
this.senha = senha;
}
// Birthday
public void setNascimento(LocalDate nascimento)
{
this.nascimento = Date.valueOf(nascimento);
}
// Gender
public void setGenero(Genero genero)
{
if(genero == null)
{
throw new NullPointerException("O gênero passado como argumento encontra-se nulo.");
}
this.genero = genero.getID();
}
/** Defines a father for this person (child).*/
public void setPai(Usuario pai)
{
// It is already?
if( this.pai == null ||
this.pai.equals(pai) == false)
{
// Remove previous father from this child.
if(this.pai != null)
{
this.pai.removeFilho(this);
}
// Defines the new father for this child.
// There may be a null assignment here!
this.pai = pai;
// Add this child to a new parent.
if(pai != null)
{
if(pai.getFilhos().contains(this) == false)
{
pai.addFilho(this);
}
}
}
}
// Same logic.
public void setMae(Usuario mae)
{
if( this.mae == null ||
this.mae.equals(mae) == false)
{
if(this.mae != null)
{
this.mae.removeFilho(this);
}
this.mae = mae;
if(mae != null)
{
if(mae.getFilhos().contains(this) == false)
{
mae.addFilho(this);
}
}
}
}
public Long getID()
{
return this.id;
}
// Name
public String getNome()
{
return this.nome;
}
public String getLogin()
{
return this.login;
}
// Password
public byte[] getSenha()
{
return this.senha;
}
// CPF = Brazil's Social ID
public String getCPF()
{
return this.cpf;
}
// Birthday
public LocalDate getNascimento()
{
return this.nascimento.toLocalDate();
}
// Gender
public Genero getGenero()
{
return Genero.getGenero(
Long.getLong(
Byte.toString(this.genero)));
}
// Father
public Usuario getPai()
{
return this.pai;
}
// Mother
public Usuario getMae()
{
return this.mae;
}
// Date and time of registration (produced by database after insertion).
public LocalDateTime getCadastro()
{
return this.cadastro.toLocalDateTime();
}
// Children of this person
public Set<Usuario> getFilhos()
{
// "Genero" is a enum type (Gender), with MALE ("HOMEM") and FEMALE ("MULHER").
if(this.getGenero() == Genero.HOMEM)
{
return Collections.unmodifiableSet(this.filhosComoPai);
}
return Collections.unmodifiableSet(this.filhosComoMae);
}
// Add a child ("filho") to this person.
public boolean addFilho(Usuario filho)
{
this.isUsuarioNula(filho);
boolean add = false;
// FATHER
if(this.getGenero() == Genero.HOMEM)
{
add = this.filhosComoPai.add(filho);
if(add)
{
if( filho.getPai() == null ||
filho.getPai().equals(this) == false)
{
Usuario paiAnterior = filho.getPai();
if(paiAnterior != null)
{
paiAnterior.removeFilho(filho);
}
filho.setPai(this);
}
}
}
// MOTHER
else
{
add = this.filhosComoMae.add(filho);
if(add)
{
if( filho.getMae() == null ||
filho.getMae().equals(this) == false)
{
Usuario maeAnterior = filho.getMae();
if(maeAnterior != null)
{
maeAnterior.removeFilho(filho);
}
filho.setMae(this);
}
}
}
return add;
}
// Removes the child ("filho") from this person.
public boolean removeFilho(Usuario filho)
{
this.isUsuarioNula(filho);
boolean rem = false;
// FATHER
if(this.getGenero() == Genero.HOMEM)
{
rem = this.filhosComoPai.remove(filho);
if(rem)
{
if( filho.getPai() == null ||
filho.getPai().equals(this) == false)
{
filho.setPai(null);
}
}
}
// MOTHER
else
{
rem = this.filhosComoMae.remove(filho);
if(rem)
{
if( filho.getMae() == null ||
filho.getMae().equals(this) == false)
{
filho.setMae(null);
}
}
}
return rem;
}
// Just to print the same message.
private void isUsuarioNula(Usuario p)
{
if(p == null)
{
throw new IllegalArgumentException("Usuario passada em argumento encontra-se nula.");
}
}
#Override
public boolean equals(Object o)
{
if (o == null)
{
return false;
}
else if (o == this)
{
return true;
}
else if (o.getClass() != this.getClass())
{
return false;
}
Usuario c = (Usuario) o;
// This ensures consistent data work, and prevents something from happening silently, without us knowing why it happened.
if(c.getCPF() == null || c.getCPF().length() <= 0)
{
throw new IllegalStateException("Valor de CPF inexistente. Uma comparação não é possível.");
}
return c.getCPF().equals(this.getCPF());
}
#Override
public int hashCode()
{
// I'm using Apacho Commons Lang.
return new HashCodeBuilder()
.append(this.getCPF()).toHashCode();
}
}
The database is already created. I'm testing this on my personal pc.
EDIT 2
I would like to share my project. Unfortunately I do not know how to use Github, and my post have almost 30k characters, so I uploaded my project (made with Eclipse Mars 2) as a war file. Here are the links:
http://www.megafileupload.com/8hon/Sistema_Teste_001.war (click on free user download to download the war file)
mirror (click on download this file to download)
To help, each package contains a file named "package-info". If in case you have any questions, check out this file. Other than that, english comments have been added for clarification.
I'm so sorry. I know it's not very convenient to download my project this way, but it was the only solution I found at the time. That way you can fully see my project.
And answering your question, I'm testing this code in the normal way, as an executable Java program. The Q classes are being generated, and my IDE is not accusing any syntax errors or anything. I'm right clicking my project and choosing "Run As..." -> "3 Java Application" to run. To generate my Q classes I'm clicking on "Run As..." -> "8 Maven generate-sources".
Well I'm embarrassed to say I didn't catch this sooner. Your syntax on your query is actually wrong
return new JPAQueryFactory(this._em)
.select(QUsuario.usuario)
.where(QUsuario.usuario.id.eq(id))
.fetchOne();
should be
return new JPAQueryFactory(this._em)
.selectFrom(QUsuario.usuario)
.where(QUsuario.usuario.id.eq(id))
.fetchOne();
Its selectFrom instead of select.
My suspicion is that the generated sources are not on the build path within your Eclipse project. Therefore when you run your Java application it is not able to find the Q source files/classes. Right click on your Eclipse Mars project and select the "Properties" option. Make sure you are on the "Source" tab and click "Add Folder" and select the target/generated-sources/java folder and Click "OK". This will add the generated-sources to your Eclipse Mars project. Then try running your Java main class.

Categories

Resources