Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update entity data using Quarkus and PanacheRepository is not working

Tags:

I'm doing some tests with Quarkus and PanacheRepository and I'm getting trouble in update an entity data. The update doesn't work, the field values are not updated.

In short: I create an entity and persist the data, after that in another request I get the entity from database using repository.findById(id);, change some field value, but the new value is not persisted in the database. I tried call repository.persist(person); after but the behavior is the same, the data is not updated.

I tried this with Quarkus version 1.9.0.Final, 1.9.0.CR1, 1.8.3.Final

I'm using postgreSQL 12. I also tried with mysql 5.7.26

I use Eclipse 2020-06 (4.16.0) only to write code and I run the application in the command line, with: ./mvnw compile quarkus:dev

I've created a brand new simple application and the behavior is the same. Here is the main configurations and some code snippets:

pom.xml

    <properties>
        <compiler-plugin.version>3.8.1</compiler-plugin.version>
        <maven.compiler.parameters>true</maven.compiler.parameters>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <quarkus-plugin.version>1.9.0.Final</quarkus-plugin.version>
        <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
        <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
        <quarkus.platform.version>1.9.0.Final</quarkus.platform.version>
        <surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-jsonb</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-hibernate-orm-panache</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-jdbc-postgresql</artifactId>
        </dependency>
    </dependencies>

application.properties:

quarkus.datasource.db-kind = postgresql
quarkus.datasource.username = theusername
quarkus.datasource.password = thepassword
quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/testpanache

# drop and create the database at startup (use `update` to only update the schema)
quarkus.hibernate-orm.database.generation = drop-and-create

Entity:

@Entity
public class Person {

    @Id @GeneratedValue public Long id;
    
    public String name;

    @Override
    public String toString() {
        return "Person [id=" + id + ", name= '" + name + "']";
    }   
}

REST Resource:

@Path("/people")
@Produces(MediaType.APPLICATION_JSON)
public class PersonResource {

    @Inject
    PersonRepository repository;
    
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public List<Person> hello() {
        return repository.listAll();
    }
    
    @POST
    @Transactional
    public void create() {
        Person person = new Person();
        person.name = "some name";
        repository.persist(person);
    }

    @PUT
    @Path("{id}")
    @Transactional
    public Person update(@PathParam("id") Long id) {
        Person person = repository.findById(id);
        person.name = "updated updated updated"; // does not work
//      repository.persist(person); // does not work
//      repository.persistAndFlush(person); // does not work
        repository.getEntityManager().merge(person); // does not work
        return person;
    }
}

Repository:

@ApplicationScoped
public class PersonRepository implements PanacheRepository<Person> {
}

I made some requests using curl to demonstrate the behavior:

$ curl -w "\n" http://localhost:8080/people
[]

$ curl -X POST http://localhost:8080/people

$ curl -w "\n" http://localhost:8080/people
[{"id":1,"name":"some name"}]

$ curl -X PUT http://localhost:8080/people/1
{"id":1,"name":"updated updated updated"}

$ curl -w "\n" http://localhost:8080/people
[{"id":1,"name":"some name"}]

So, the list starts empty, the second POST request creates a Person with "some name", as shown by the third request; the fourth request does a PUT that is intended to change the name to "updated updated updated", but the fifth request shows the name was not updated.

Although it's not needed, I tried repository.persist(person);, repository.persistAndFlush(person);, and even repository.getEntityManager().merge(person); (one each time) as show in the PersonResource snippet above. But none of them made effect.

What I am missing?

PS.: I tried to change my entity to extends PanacheEntity and used Person.findById(id); to find the entity, this way the subsequent updates did make effect. But it's not my point, I wanna use PanacheRepository and want to understand what I'm missing with this.

like image 251
Isabel Tiburski Avatar asked Oct 23 '20 16:10

Isabel Tiburski


1 Answers

Please consider accessing your entity using getter/setter, so Hibernate Proxies will work properly.

@Entity
public class Person {

    @Id @GeneratedValue public Long id;
    
    private String name;  // <--- private field

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name= '" + name + "']";
    }   
}

and in your resource:


    @PUT
    @Path("{id}")
    @Transactional
    public Person update(@PathParam("id") Long id) {
        Person person = repository.findById(id);
        person.setName("updated updated updated");  // <--- this way works
        repository.persist(person);
        return person;
    }
like image 97
Tiago Aquino Avatar answered Sep 29 '22 11:09

Tiago Aquino