2016-10-11 66 views
0

增加執行時間,我有以下實體:柱上添加@Convert由超過10倍

@Data 
@Entity 
@Table(name="\"Customer\"") 
public class Customer { 
    @Id 
    @SequenceGenerator(name="customer_id_seq", 
      sequenceName="customer_id_seq", 
      allocationSize=1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, 
      generator="customer_id_seq") 
    private long id; 
    private String firstName; 
    @Convert(converter = LastNameEncryption.class) 
    private String lastName; 
} 

其中LastNameEncryption.java是:

public class LastNameEncryption implements AttributeConverter<String,String> { 

    private static SecretKeySpec secretKey; 
    private final static String peselKey = "somekey"; 

    @Override 
    public String convertToDatabaseColumn(String attribute) { 
     try 
     { 
      setKey(); 
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, secretKey); 
      return Base64.getEncoder().encodeToString(cipher.doFinal(attribute.getBytes("UTF-8"))); 
     } 
     catch (Exception e) 
     { 
      System.out.println("Error while encrypting: " + e.toString()); 
     } 
     return null; 

    } 

    public String convertToEntityAttribute(String dbData) { 
     try { 
      setKey(); 
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); 
      cipher.init(Cipher.DECRYPT_MODE, secretKey); 
      return new String(cipher.doFinal(Base64.getDecoder().decode(dbData))); 
     } 
     catch (Exception e) 
     { 
      System.out.println("Error while decrypting: " + e.toString()); 
     } 
     return null; 

    } 

    public static void setKey() { 
     MessageDigest sha = null; 
     byte[] key; 
     try { 
      key = peselKey.getBytes("UTF-8"); 
      sha = MessageDigest.getInstance("SHA-1"); 
      key = sha.digest(key); 
      key = Arrays.copyOf(key, 16); 
      secretKey = new SecretKeySpec(key, "AES"); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

這應是一個ecnryption /解密機制行事。

但是,當我添加這個時,簡單查詢的執行時間從200ms左右增加到5.5s(原始主題here)。然後我發現,當我註釋@Comment(...)註釋時,查詢再次平穩運行。

我是否犯了錯誤,或者這是正常行爲?

注意

當我比較的執行時間,只有3表中的實體。這裏是方法的執行時間日誌:

Execution time of convertToEntityAttribute: 5193 
Execution time of convertToEntityAttribute: 0 
Execution time of convertToEntityAttribute: 0 
Execution time of convertToEntityAttribute: 0 

出於某種原因,它需要幾乎5.2s到首次加密 - 那麼,時間小於1毫秒小。

+0

您是否嘗試檢查轉換器的時間? –

+0

@AmerQarabsa,我發佈了執行時間日誌 – uksz

回答

0

使用jvisualvm(包含在oracle jvm發行版中)來查明什麼是緩慢的。

使用Sampler選項卡,單擊CPU按鈕即可(與註釋一次不@Convert,一次)觸發緩慢的操作之前,當操作完成的Stop然後snapshot按鈕點擊。然後比較兩個執行配置。你會看到確切的方法是花時間。

第一次使用加密工具或hibernate或其他任何東西時,它可能是一個懶惰的初始化。

如果你很難分析CPU採樣結果,請不要猶豫,回到這裏並用它更新你的問題(你可以導出快照)。


不相關的問題,我不知道它是應忽略在轉換異常(你在例外的情況下,返回null):可能會丟失數據。

另外,要避免這樣做:

System.out.println("Error while encrypting: " + e.toString()); 

例如,在NullPointerException情況下,你會得到在控制檯上:Error while encrypting: java.lang.NullPointerException: null。只要你有堆棧跟蹤,一個空指針確實很容易修復。在這裏,你將不得不猜測它發生了什麼。