OptimisticLockException с JPA / Hibernate при попытке чтения зашифрованного текста - PullRequest
2 голосов
/ 01 февраля 2012

Нам нужно зашифровать строки при их сохранении с помощью JPA и расшифровать их при чтении.Прежде всего, мы не можем использовать некоторые настройки hibernate или любые другие файлы конфигурации, потому что наши свойства являются общими.Это означает, что наши свойства выглядят следующим образом (просто, мы уже реализовали некоторую обработку здесь):

@Entity
@Table(name = "PROPERTY")
@Access(AccessType.FIELD)
public class Property implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "PRO_ID")
    private long id;

    @Version
    @Temporal(value = TemporalType.TIMESTAMP)
    @Column(name = "PRO_VERSION")
    private Date version;

    @Column(name = "PRO_KEY")
    private String key;

    @Transient
    private String value;

    @Column(name = "PRO_ENCRYPTED")
    private boolean encrypted = false;

    public long getId()
    {
        return id;
    }

    public void setId(long id)
    {
        this.id = id;
    }

    public Date getVersion()
    {
        return version;
    }

    public void setVersion(Date version)
    {
        this.version = version;
    }

    public String getKey()
    {
        return key;
    }

    public void setKey(String key)
    {
        this.key = key;
    }

    public String getValue()
    {
        return value;
    }

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

    public boolean isEncrypted()
    {
        return encrypted;
    }

    public void setEncrypted(boolean encrypted)
    {
        this.encrypted = encrypted;
    }

    @Access(AccessType.PROPERTY)
    @Column(name = "PRO_VALUE")
    protected String getValueDatabase()
    {
        // TODO: add decryption
        return value;
    }

    protected void setValueDatabase(String value)
    {
        // TODO: add encryption
        this.value = value;
    }
}

(Мы можем различить, какое свойство должно быть зашифровано с помощью метода isEncrypted (). Для него установлено значение trueили ложь в зависимости от имущества).Класс Out Encryptor (упрощенный) работает с Jasypt:

public final class MyEncrypter
{
    private static final String password = "AHKG@a4SjHH5%j%974";
    private static final StandardPBEStringEncryptor encryptor;

    static 
    {
        encryptor = new StandardPBEStringEncryptor();
        encryptor.setPassword(password);
    }

    public final static String encrypt(String string)
    {
           return encryptor.encrypt(string);
    }

        public final static String decrypt(String encrypted)
        {
            return encryptor.decrypt(encrypted);
        }
}

Шифрование / дешифрование работает.На самом деле вся наша настойчивость работает.Мы можем сохранить зашифрованные данные.НО, когда мы читаем зашифрованные данные, мы получаем следующее:

javax.persistence.OptimisticLockException: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [at.jit.remind.jee.domain.context.model.Property#10]

Странно то, что это происходит только в том случае, если Hibernates пытается обновить зашифрованный текст .Но этого не происходит, когда мы псевдо-шифруем и псевдо-дешифруем наш текст.Это означает, что мы переворачиваем текст, сохраняем перевернутый текст с помощью Hibernate и «расшифровываем» его, когда Hibernate пытается его обновить.Итак, вся наша обработка работает, но что может быть причиной того, что она не работает, когда мы используем «настоящее» шифрование?Любые идеи?

(Опять же, само шифрование и дешифрование работает. Я позволю запустить его в разных классах JUnit, чтобы убедиться в этом.)

Ответы [ 2 ]

1 голос
/ 01 февраля 2012

Мы решили использовать другое шифрование, потому что jasypt явно делает что-то странное с Hibernate.Кажется, что это шифрование / дешифрование создает какой-то «грязный флаг» для Hibernate, поэтому Hibernate пытается обновить записи в базе данных, хотя шифрование изменяет значения одновременно.Не было возможности его изолировать.

0 голосов
/ 01 февраля 2012

Это потому, что ваш объект все еще подключен к сеансу гибернации и его внутреннее состояние изменилось.Попробуйте сначала вызвать session.evict (объект), а затем измените текст, который должен быть зашифрован.

...