gpt4 book ai didi

hibernate - 我想知道 Hibernate 是否有办法执行 ColumnTransformer 的编程配置?

转载 作者:行者123 更新时间:2023-12-03 08:22:01 25 4
gpt4 key购买 nike

我目前有一个这样注释的字段:

ColumnTransformer(
read="AES_DECRYPT(C_first_name, 'yourkey')",
write="AES_ENCRYPT(?, 'yourkey')")
public String getFirstName() {
return firstName;
}

这与 Mysql 数据库一起正常工作,但我需要此配置是可选的,因为我们的应用程序可以根据启动参数使用另一个数据库 (HsqlDB)。所以我需要的是一种仅在使用特定启动参数时使用 ColumnTransformer 的方法(对于 HsqlDB 没有 ColumnTransformer,它不能使用“AES_ENCRYPT”)

有人可以帮我弄这个吗 ?

最佳答案

我有同样的问题,我希望 key 是可配置的。我为此项目找到的唯一解决方案是在运行时更新注释值。是的,我知道这听起来很糟糕,但据我所知没有其他办法。

实体类:

@Entity
@Table(name = "user")
public class User implements Serializable {
@Column(name = "password")
@ColumnTransformer(read = "AES_DECRYPT(password, '${encryption.key}')", write = "AES_ENCRYPT(?, '${encryption.key}')")
private String password;
}

我实现了将 ${encryption.key} 替换为其他值的类(在我的例子中是从 Spring 应用程序上下文加载的)
import org.hibernate.annotations.ColumnTransformer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.util.Map;

import javax.annotation.PostConstruct;

@Component(value = "transformerColumnKeyLoader")
public class TransformerColumnKeyLoader {

public static final String KEY_ANNOTATION_PROPERTY = "${encryption.key}";

@Value(value = "${secret.key}")
private String key;

@PostConstruct
public void postConstruct() {
setKey(User.class, "password");
}

private void setKey(Class<?> clazz, String columnName) {
try {
Field field = clazz.getDeclaredField(columnName);

ColumnTransformer columnTransformer = field.getDeclaredAnnotation(ColumnTransformer.class);
updateAnnotationValue(columnTransformer, "read");
updateAnnotationValue(columnTransformer, "write");
} catch (NoSuchFieldException | SecurityException e) {
throw new RuntimeException(
String.format("Encryption key cannot be loaded into %s,%s", clazz.getName(), columnName));
}
}

@SuppressWarnings("unchecked")
private void updateAnnotationValue(Annotation annotation, String annotationProperty) {
Object handler = Proxy.getInvocationHandler(annotation);
Field merberValuesField;
try {
merberValuesField = handler.getClass().getDeclaredField("memberValues");
} catch (NoSuchFieldException | SecurityException e) {
throw new IllegalStateException(e);
}
merberValuesField.setAccessible(true);
Map<String, Object> memberValues;
try {
memberValues = (Map<String, Object>) merberValuesField.get(handler);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
Object oldValue = memberValues.get(annotationProperty);
if (oldValue == null || oldValue.getClass() != String.class) {
throw new IllegalArgumentException(String.format(
"Annotation value should be String. Current value is of type: %s", oldValue.getClass().getName()));
}

String oldValueString = oldValue.toString();
if (!oldValueString.contains(TransformerColumnKeyLoader.KEY_ANNOTATION_PROPERTY)) {
throw new IllegalArgumentException(
String.format("Annotation value should be contain %s. Current value is : %s",
TransformerColumnKeyLoader.KEY_ANNOTATION_PROPERTY, oldValueString));
}
String newValueString = oldValueString.replace(TransformerColumnKeyLoader.KEY_ANNOTATION_PROPERTY, key);

memberValues.put(annotationProperty, newValueString);
}
}

应该运行此代码 之前 创建实体管理器。在我的情况下,我使用了依赖(对于 xml 配置或 @DependsOn 用于 java 配置)。
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="transformerColumnKeyLoader"> ... </bean>

关于hibernate - 我想知道 Hibernate 是否有办法执行 ColumnTransformer 的编程配置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19541252/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com