Автоматически применять функцию преобразования поля в Hibernate - PullRequest
2 голосов
/ 30 июля 2009

У меня есть таблица базы данных с полем, из которого мне нужно читать и писать через Hibernate. Это строковое поле, но содержимое зашифровано. И по различным причинам (например, необходимость сортировки значений в виде простого текста) функции шифрования / дешифрования реализуются внутри базы данных, а не в Java.

Проблема, с которой я сейчас борюсь, заключается в том, чтобы найти способ вызывать функции шифрования / дешифрования в сгенерированном Hibernate SQL везде, на которое ссылается поле, и способом, который прозрачен для кода моего приложения. Это возможно? Я рассмотрел поддержку Hibernate для «производных» свойств, но, к сожалению, этот подход не поддерживает поля чтения-записи. Любые идеи приветствуются.

Ответы [ 5 ]

4 голосов
/ 30 июля 2009

Я не думаю, что есть способ сделать шифрование, как вы его описали, полностью прозрачным для вашего приложения. Самое близкое, что вы можете получить, это сделать его прозрачным вне сущности. В вашем классе сущности:

@Entity
@SQLInsert(sql="INSERT INTO my_table(my_column, id) VALUES(encrypt(?),?)")
@SQLUpdate( sql="UPDATE my_table SET my_column = encrypt(?) WHERE id = ?")
public class MyEntity {

  private String myValue;

  ....

  @Formula("decrypt(my_column)")
  public String getValue() {
    return myValue;
  }

  public void setValue(String value) {
    myValue = value;
  }

  @Column (name="my_column")
  private String getValueCopy() {
    return myValue;
  }

  private void setValueCopy(String value) {
  }

}

value отображается как производное свойство, вы должны иметь возможность использовать его в запросах.
valueCopy является приватным и используется для обхода производного свойства только для чтения.
SQLInsert и SQLUpdate - это чёрная магия вуду для принудительного шифрования при вставке / обновлении. Обратите внимание, что порядок параметров IS важен, вам нужно выяснить, в каком порядке Hibernate будет генерировать параметры без использования пользовательской вставки / обновления, а затем скопировать его.

1 голос
/ 29 октября 2009

На самом деле, в конце концов, я пошел другим путем и отправил патч в Hibernate. На прошлой неделе он был посвящен транку, и я думаю, что это будет в следующем выпуске после 3.5. Теперь в сопоставлениях свойств можно указывать выражения «чтения» и «записи» SQL для вызова функций SQL или выполнения какого-либо другого преобразования на стороне базы данных.

1 голос
/ 30 июля 2009

У вас может быть внутренний триггер для базы данных, который при извлечении расшифровывает значение и заменяет возвращаемый результат, а при вставке шифрует значение и заменяет сохраненный результат зашифрованным значением. Вы также можете сделать это с помощью обертки представления - то есть иметь триггер вставки в представлении, и представление автоматически расшифровывает значение.

Для лучшего объяснения: имейте представление, которое расшифровывает значение, и триггер при вставке, который шифрует значение, связанное с представлением.

0 голосов
/ 31 июля 2009

Почему бы просто не использовать шифрование сервера SQl, которое, по-видимому, уже используется, вызвав хранимый процесс в Hibernate вместо того, чтобы позволить Hibernate генерировать запрос?

0 голосов
/ 30 июля 2009

Предполагая, что у вас есть доступ к алгоритму шифрования / дешифрования из Java, я бы настроил свой сопоставленный класс примерно так:

public class encryptedTable {
    @Column(name="encrypted_field")
    private String encryptedValue;

    @Transient
    private String value;

    public String getEncryptedValue() {
        return encryptedValue;
    }

    public String getValue() {
        return value;
    }

    public void setEncryptedValue(String encryptedValue) {
        this.encryptedValue = encryptedValue;
        this.value = decrypt(encryptedValue);
    }

    public void setValue(String value) {
        this.value = value;
        this.encryptedValue = encrypt(value);
    }
}

А затем используйте get / set Value в качестве средства доступа в вашей программе и оставьте get / set EncryptedValue для использования Hibernates при доступе к базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...