简体   繁体   中英

Java Quarkus Panache (Hibernate) doesn't update entity property

I have a PSU entity:

@Entity
public class Psu extends PanacheEntityBase {
    @Id
    @GeneratedValue
    public UUID uuid;

    @Column(nullable = false, length = 50)
    public String username;
    public Integer coins;
    public String firebaseRegistrationToken;

    public void setCoins(int coins){
        this.coins = coins;
    }

    public int getCoins(){
        return coins;
    }

    public static Psu findByUsername(String username){
        return find("username", username).firstResult();
    }
} 

And a function in my PsuService class:

@Transactional
public Transaction changeBalance(Transaction transaction){
    Psu psuSender = Psu.findById(transaction.senderId);
    psuSender.coins = psuSender.coins - transaction.amount;
    Psu.persist(psuSender);

    transaction.status = TransactionStatus.PROCESSED;

    return transaction;
}

When I log, after the function call, all users and their amount of coins it shows that the coins are updated for the right person:

List<Psu> allPsu = Psu.findAll().list();
for(Psu psu : allPsu){
    System.out.println("ID: " + psu.uuid + " coins: " + psu.coins);
}

When I retrieve the balance of the updated user via the API:

@GET
@Path("psu/getBalance/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
public String getBalanceById(@PathParam("uuid") UUID uuid) {
    List<Psu> allPsu = Psu.findAll().list();
    for(Psu psu : allPsu){
        System.out.println("ID: " + psu.uuid + " coins: " + psu.coins);
    }

    return gson.toJson(psuService.getBalanceById(uuid));
}

Using this method in the PsuService class:

@Transactional
public int getBalanceById(UUID uuid){
    Psu psu = Psu.findById(uuid);
    return psu.getCoins();
}

Then it returns the old balance which is not updated.

Does anyone know why I can't update the balance?

  • PsuService extends PanacheEntityBase
  • PsuService is @ApplicationScoped

EDIT When doing an update with:

Psu.update("coins = ?1 where id= ?2", 10, transaction.senderId);

I receive the error:

ERROR [io.qua.sch.run.SimpleScheduler] (executor-thread-1) Error occured while executing task for trigger IntervalTrigger [id=1_com.msp.sqs.MessageQueue_ScheduledInvoker_receiveMessages_e721e20dd5fdaa8a94c141
a7768b0311d6f32352, interval=1000]: javax.persistence.TransactionRequiredException: Executing an update/delete query

I think it's not updated because you are using persist with an existing entity. Because the entity is managed and exists, you can change the code this way:

@Transactional
public Transaction changeBalance(Transaction transaction){
    Psu psuSender = Psu.findById(transaction.senderId);
    psuSender.coins = psuSender.coins - transaction.amount;
    // Psu.persist(psuSender); <-- Remove this

    transaction.status = TransactionStatus.PROCESSED;
    return transaction;
}

Changes will be propagated to the database when the transaction is committed because the entity is in a managed state.

I think instead of writing

Psu.persist(psuSender);

You should write

psuSender.persist();

While writing the code I accidentally deleted @Inject...

However, Quarkus didn't gave me any error or something.

After Injecting the psuService class everything worked fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM