2016-09-09 1 views
0

Je suis presque sûr que ce scénario est courant: j'ai une table avec une colonne qui sert de compteur. J'ai besoin d'incrémenter la valeur et j'ai besoin de connaître la valeur incrémentée.Compteur utilisant les référentiels JPA de Spring

que je pouvais faire quelque chose comme ça avec les dépôts JPA de printemps:

@Transactional 
public getNextValue(){ 
    DataPO po = repository.find("someId"); 
    po.setCounter(po.getCounter+1); 
    repository.save(po); 
} 

L'inconvénient de ce qu'il utilise le verrouillage et est donc lente.

je lis au sujet d'une approche à l'aide LAST_INSERT_ID pour le faire efficacement, mais les exemples que je trouve ne pas utiliser les dépôts, ils utilisent EntityManager directement: sample

Ceci est de la page liée:

Y a-t-il un moyen de le faire avec les dépôts JPA de Spring?
Query query = entityManager.createNativeQuery("UPDATE counter SET value = LAST_INSERT_ID(value + 1) WHERE name = :name"); 
query.setParameter("name", client.getName()); 
query.executeUpdate(); 

query = entityManager.createNativeQuery("SELECT LAST_INSERT_ID()"); 
long value = ((BigInteger) query.getSingleResult()).longValue(); 
value = value - 1; 

Je ne trouve rien dans la documentation: Spring's JPA Repositories

Y a-t-il une autre approche efficace que je peux suivre avec les dépôts JPA?

Merci d'avance pour votre aide!

+0

Je pensais que c'était clair quand je parlais de verrouillage. J'aurais dû être plus précis à ce sujet. C'est multi-threadé et le compteur n'est pas ID. J'ai besoin de mettre à jour le compteur et de le récupérer et cela sans introduire de conditions de course. –

Répondre

1

Vous pouvez utiliser Native Queries à partir de Spring Data JPA.

Dans votre cas:

public interface CounterRepository extends JpaRepository<Counter, Long>{ 

    @Modifying 
    @Query(value = "UPDATE Counter SET value = LAST_INSERT_ID(value + 1) WHERE name = ?1", nativeQuery = true) 
    int updateCounterByName(String name); 

    @Query(value = "SELECT LAST_INSERT_ID()", nativeQuery = true) 
    int getLastInsertId(); 

    Counter findOneByName(String name); 

} 

Commander le Complete Project sur mon dépôt GitHub.

+0

Cela pourrait fonctionner. Je vais essayer ça demain matin. Je vous remercie –