2016-09-09 9 views
0

これは一般的なシナリオであると私は確信しています - 私はカウンタとして機能するカラムを持つテーブルを持っています。私は値を増やし、増分された値を知る必要があります。Counter SpringのJPAリポジトリを使用する

私はSpringのJPAリポジトリとこのような何か行うことができます:

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

をこれの欠点は、それがロック使用していますので、遅いです。私はを使用してのアプローチについて読ん

は、これを効率的に行うためにをLAST_INSERT_IDが、私はリポジトリを使用していない見つかった例は、彼らが直接のEntityManagerを使用します。sample

は、これはリンク先のページからです。

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; 

SpringのJPAリポジトリでこれを行う方法はありますか?ドキュメント内に何も見つかりません:Spring's JPA Repositories

私はJPAリポジトリに従うことができる他の効率的なアプローチはありますか?

ご協力いただきありがとうございます。

+0

私はロックについて書きましたが、それは明らかです。私はそれをより正確にすべきだった。マルチスレッドで、カウンタはIDなしです。私はカウンターを更新して、これを効率的に競合条件の導入なしに取得する必要があります。 –

答えて

1

Native QueriesはSpring Data JPAから利用できます。あなたのケースでは

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); 

} 

チェックアウト私のGitHubリポジトリにComplete Project

+0

これはうまくいく可能性があります。私は明日の朝にそれを試みるつもりです。ありがとうございました –

関連する問題