2017-09-08 1 views
0

Ich habe einen verschlüsselten Wert in der Datenbank und möchte ihn vor dem Senden an das Front-End entschlüsseln. Wenn ich den Wert zuerst als verschlüsselt speichern, sieht er wie -kKwj477382jle34nw in der Datenbank aus. Aber wenn ich meine getClientByUsername() Funktion anrufe, die ich die Entschlüsselungssache in dieser Funktion mache, ändert sich der Wert in der Datenbank auch automatisch, wenn ich den entschlüsselten Wert im Objekt vor dem Senden des Objekts an das Frontend setze.Hibernate aktualisiert Daten beim Aufruf von Setter

@Transactional 
public ResponseEntity <Client> getClientByUsername(String username) throws Exception { 
    Client loggedClient = clientDAO.findByUsername(username); 
    String data = loggedClient.getCreditCardNo(); 
    if (null != data) { 
    @SuppressWarnings("static-access") 
    byte[] encrypted = base64.decodeBase64(data); 
    SecretKeySpec secretKeySpec = new SecretKeySpec(encryptionKey.getBytes(), algorithm); 
    Cipher cipher = Cipher.getInstance(algorithm); 
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); 
    decrypted = cipher.doFinal(encrypted); 
    loggedClient.setCreditCardNo(new String(decrypted)); 
    } 
    return new ResponseEntity <Client> (loggedClient, HttpStatus.OK); 
} 

Hier ist, wie ich den Wert speichern verschlüsselt:

@Transactional 
public boolean clientUpdate(String client) { 
    str = updateclient.getCreditCardNo(); 
    if (null != str) { 
     SecretKeySpec secretKeySpec = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), algorithm); 
     Cipher cipher = Cipher.getInstance(algorithm); 
     cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); 
     encrypted = cipher.doFinal(str.getBytes("UTF-8")); 
     updateclient.setCreditCardNo(base64.encodeToString(encrypted)); 
     return clientDAO.updateProfileClient(updateclient); 
    } 

Wie kann ich Hibernate blockieren den Wert zu ändern, wenn Setter Aufruf?

aktualisieren

@PersistenceContext 
private EntityManager entityManager; 

public Client findByUsername(String username) throws Exception { 
     Query query = entityManager.createNamedQuery("Client.findByUsername"); 
     query.setParameter("username", username); 
     List result = query.getResultList(); 
     return result.size() > 0 ? (Client) result.get(0) : null; 
    } 
+0

Dies ist ein gutes Beispiel dafür, warum Sie Ihre Entität von Ihrem dto für die Antwort trennen sollten. edit: und Controller-Logik von Transaktionslogik zu – Zeromus

+0

@Zeromus nicht notwendig. Ich persönlich hasse diese Trennung und kämpfe immer in Projekten dagegen. – Andremoniy

+0

Angenommen, es ist eine Vorliebe für alle ... aber ich finde es viel sauberer zu trennen Logik und vermeiden diese Art von Problemen beim Aufbau Antworten – Zeromus

Antwort

2

Sie müssen evict dieses Objekt aus Sitzung Hibernate:

void evict(Object object) throws HibernateException 

Entfernen Sie diese Instanz aus dem Sitzungscache. Änderungen an der Instanz werden nicht mit der Datenbank synchronisiert. Diese Operation kaskadiert zu verknüpften Instanzen, wenn die Zuordnung mit cascade = "evict" zugeordnet ist.

P.S. Nur gedacht, dass Sie auch einen anderen Ansatz in Betracht ziehen können. Sie können ein Feld in einer Bean erstellen, das als markiert wird, d. H. Von der Datenbank entkoppelt ist, und es beispielsweise mit creditCardNoDecrypted benennen. Das verschlüsselte Feld markiert als @JsonIngore (oder was auch immer Sie für die Serialisierung verwenden).

+0

Ich glaube mit evict ist besser Ansatz, aber ich habe nicht herausgefunden, wie ich es tun kann – Eniss

+0

Dies sollte in 'clientDAO.findByUsername' Methode – Andremoniy

+0

Ich aktualisierte meine Antwort durch Hinzufügen' findByUsername' Funktion. Ich benutze 'EntityManager'. Ich denke, ich brauche 'hibernate.cfg.xml', um' SessionFactory' zu verwenden, das von 'Session' benötigt wird, aber ich habe es nicht. Also macht 'entityManager.refresh (obj)' dasselbe wie 'evict (Object obj)' oder was soll ich tun? – Eniss

Verwandte Themen