I am currently trying some things in JPA, and seem to have hit a block that i cannot figure out and cant find online.
I am trying to retrieve a list of the customers in de PostgreSQL DB, this can be done by writing the transaction manually or using the JTA @Transactional annotation. However the manual implementation is working, and the @Transactional is not.
I have written the manual transaction like so:
package com.example.demo.service;
import com.example.demo.dto.CustomerDto;
import com.example.demo.mapper.CustomerMapper;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
//import javax.transaction.Transactional;
import models.Customer;
import java.util.ArrayList;
import java.util.List;
@ApplicationScoped
public class CustomerRepository {
EntityManagerFactory entityManagerFactory = null;
EntityManager entityManager = null;
public List<CustomerDto> findAllManual() {
entityManagerFactory = Persistence.createEntityManagerFactory("jpa-postgres");
entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
List<Customer> customers = entityManager.createQuery("SELECT c FROM Customer c", Customer.class)
.getResultList();
List<CustomerDto> customerDtos = new ArrayList<>();
customers.forEach(t -> customerDtos.add(CustomerMapper.toDto(t)));
System.out.println("Komt hier wel. Print evt entity manager: " + entityManager);
System.out.println("Komt hier wel. Print evt customers: " + customers);
System.out.println("Komt hier wel. Print evt customersDTO: " + customerDtos);
entityManager.close();
return customerDtos;
}
And this returns my list properly. Except the following does not.
package com.example.demo.service;
import com.example.demo.dto.CustomerDto;
import com.example.demo.mapper.CustomerMapper;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.persistence.Persistence;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
//import javax.transaction.Transactional;
import models.Customer;
import java.util.ArrayList;
import java.util.List;
@ApplicationScoped
public class CustomerRepository {
@PersistenceContext(unitName = "jpa-postgres")
private EntityManager em;
@Transactional
public List<CustomerDto> findAll() {
List customers = em.createQuery("SELECT c FROM Customer c", Customer.class)
.getResultList();
List<CustomerDto> customerDtos = new ArrayList<>();
customers.forEach(t -> customerDtos.add(CustomerMapper.toDto((Customer) t)));
System.out.println("Komt hier wel. Print evt entity manager: " + em);
System.out.println("Komt hier wel. Print evt customers: " + customers);
System.out.println("Komt hier wel. Print evt customersDTO: " + customerDtos);
return customerDtos;
}
}
This returns an empty list.
What I think the problem is: the @Transactional method does not connect to the DB which s why is returns an empty list. But I can't seem to figure out why that is.
The persistence.xml :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
version="3.0">
<persistence-unit name="jpa-postgres">
<class>models.Customer</class>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/filmland" />
<property name="jakarta.persistence.jdbc.user" value="postgres" />
<property name="jakarta.persistence.jdbc.password" value="root" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="jakarta.persistence.schema-generation.database.action" value="create" />
</properties>
</persistence-unit>
</persistence>
So it should use the same "jpa-postgres" as the manual transaction does the sys outs print the following.
Manual method:
16:20:02,343 INFO [stdout] (default task-1) Hibernate:
16:20:02,343 INFO [stdout] (default task-1) select
16:20:02,343 INFO [stdout] (default task-1) c1_0.id,
16:20:02,343 INFO [stdout] (default task-1) c1_0.email,
16:20:02,343 INFO [stdout] (default task-1) c1_0.password
16:20:02,344 INFO [stdout] (default task-1) from
16:20:02,344 INFO [stdout] (default task-1) customer c1_0
16:20:02,347 INFO [stdout] (default task-1) Komt hier wel. Print evt entity manager: SessionImpl(394828776<open>)
16:20:02,348 INFO [stdout] (default task-1) Komt hier wel. Print evt customers: [Customer(id=1, [email protected], password=mooiman), Customer(id=2, [email protected], password=mooieding)]
16:20:02,348 INFO [stdout] (default task-1) Komt hier wel. Print evt customersDTO: [com.example.demo.dto.CustomerDto@52fb491a, com.example.demo.dto.CustomerDto@76e5d921]
The @Transactional method:
[2023-11-16 04:14:59,878] Artifact demo:war exploded: Deploy took 2,428 milliseconds
16:16:36,579 INFO [stdout] (default task-1) Hibernate:
16:16:36,579 INFO [stdout] (default task-1) select
16:16:36,579 INFO [stdout] (default task-1) c1_0.id,
16:16:36,580 INFO [stdout] (default task-1) c1_0.email,
16:16:36,580 INFO [stdout] (default task-1) c1_0.password
16:16:36,580 INFO [stdout] (default task-1) from
16:16:36,580 INFO [stdout] (default task-1) customer c1_0
16:16:36,586 INFO [stdout] (default task-1) Komt hier wel. Print evt entity manager: org.jboss.as.jpa.container.TransactionScopedEntityManager@2d71f100
16:16:36,587 INFO [stdout] (default task-1) Komt hier wel. Print evt customers: []
16:16:36,587 INFO [stdout] (default task-1) Komt hier wel. Print evt customersDTO: []
Anyone able to help me understand why this is happening and why the Transactional is implement in the wrong way by me ?