2017-03-11 7 views
0

私のグループクラスには、誰が呼び出しようとしているかによって操作を許可する必要があるかどうかをJavaコードが検証するために使用するトークン属性があります。英数字キーを生成し、グループコンストラクタ内にトークンを割り当てるために使用しているコードがあります。例えばバッチインサートの生成値で重複を防ぐ方法

public Group(){ 
    super(); 
    this.token = Crypt.generate(30); // length of key 
} 

これが正常に動作していると私のデータベースが今小さく、しかし、私は、生成されたキーがすでに存在する可能性があることを考えています。この場合、データをデータベースに挿入しようとすると、org.springframework.dao.DataIntegrityViolationExceptionが返されます。私はtry/catchですべてのinsert文をラップして再試行することについて議論しましたが、私は通常バッチプロセスのGroupテーブルに現在その時点で挿入しているので、正常に保存された可能性のあるレコードを確認する必要があります。

List<Group> groups = new ArrayList<>(); 
groups.add(new Group("grp1"); 
groups.add(new Group("grp2"); 
groups.add(new Group("grp3"); 

try { 
    groupRepository.save(groups); 

} catch (DataIntegrityViolationException e){ 

    List<Group> secondAttemptGroups = new ArrayList<>(); 

    for(Group g : groups){ 

     Group insertedGroup = groupRepository.findByName(g.getName()); 

     if(insertedGroup == null){ 

      secondAttempGroups.add(new Group(g.getName()); 
     } 
    } 
    if(!(secondAttempGroups.isEmpty()){ 

     try { 

      group.repository.save(secondAttempGroups); 

     } catch(DataIntegrityViolationException e2){ 
      // ... 
     } 
    } 
} 

これを防ぐには、より良い方法が必要です。

+0

このトークンとは何ですか。それはちょうどランダムなユニークなキーですか?その場合は、UUIDを使用します。 –

+0

または、データベースで鍵を作成させます。 – Robert

+0

UUIDとは何ですか? – jDub9

答えて

0

問題についてもっと詳しく考えた後、データベース全体を自分のコードに組み込むことなく、Spring JPAでトークンを検証できると思ったのです。これは私が思いついたものです。

public static List<Group> validateTokens(List<Group> groups, int iterations){ 

    LOGGER.info("Validating Tokens: Iteration #" + iterations); 

    boolean dirtyToken = false; 

    // Validate that the groups provided don't contain duplicate tokens. 

    Set<String> tokenSet = new HashSet<>(); 

    for(Group g1 : groups){ 
     tokenSet.add(g1.getToken()); 
    } 
    if(tokenSet.size() != groups.size()){ 
     dirtyToken = true; 

     for(Group g2 : groups){ 
      g2.setToken(Crypt.generate(TOKEN_LENGTH)); 
     } 
    } 

    // Validate that the groups provided don't contain tokens that are already present in the database. 

    for(Group g3 : groups){ 
     Group databaseGroup = groupRepository.findByToken(g3.getToken()); 

     if(databaseGroup != null){ 
      dirtyToken = true; 
      g3.setToken(Crypt.generate(TOKEN_LENGTH)); 
     } 
    } 
    if(dirtyToken && iterations-- > 0){ 
     return validateTokens(groups, iterations); 
    } 
    else if(dirtyToken && iterations < 1){ 
     LOGGER.warn("Tokens could not be validated and Unique Constraint Violtation will be thrown. " + 
        "Perhaps it's time to increase the token length from " + TOKEN_LENGTH + "."); 
     return groups; 
    } 
    else { 
     return groups; 
    } 

上記の再帰的な方法が機能します。 @Robert私はデータベース生成値を考慮しませんでしたが、開発中に私はh2をデータベースとしてのみ使用します。そのアプローチはまだ実行可能で、おそらくより簡単でしょうか?

関連する問題