Why does @Transactional not work, but writing it manually does work

76 Views Asked by At

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 ?

0

There are 0 best solutions below