AttributeConverter的接口(interface)如下:
public interface AttributeConverter<X,Y> {
public Y convertToDatabaseColumn (X attribute);
public X convertToEntityAttribute (Y dbData);
}
在我的实现中,我想了解一些有关转换器运行的实体和实体的字段。例如:这个转换器是否应该为应用程序解密这个字段?
JAX-RS 有
@Context
的概念这很方便。好奇 JPA 是否有等效的概念。
最佳答案
我不认为你可以用普通的 JPA 转换器来做到这一点(见 this)。但是你可以用 Hibernate custom types实现 DynamicParameterizedType
界面。
和简单的例子:
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Properties;
import javax.persistence.Column;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.DynamicParameterizedType;
import org.hibernate.usertype.UserType;
public class MyConverter implements UserType, DynamicParameterizedType
{
private int sqlType;
private Object entity; // com.example.hibernate.Account
private int columnLength;
public MyConverter()
{
}
@Override
public void setParameterValues(Properties parameters)
{
sqlType = getSqlType(parameters.get(RETURNED_CLASS));
Object entity = parameters.get(ENTITY);
ParameterType reader = (ParameterType) parameters.get(PARAMETER_TYPE);
this.columnLength = getLength(reader);
}
private int getSqlType(Object field)
{
if (field instanceof Long) return Types.BIGINT;
if (field instanceof LocalDateTime) return Types.TIMESTAMP;
return Types.VARCHAR;
}
private int getLength(ParameterType reader)
{
int length = -1; // default length
for (Annotation annotation : reader.getAnnotationsMethod()){
if (annotation instanceof Column) {
length = ((Column) annotation).length();
}
}
return length;
}
@Override
public int[] sqlTypes()
{
return new int[] {sqlType};
}
@Override
public Class<?> returnedClass()
{
return String.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException
{
return Objects.equals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException
{
return Objects.hashCode(x);
}
@Override
public Object nullSafeGet(ResultSet rs,
String[] names,
SharedSessionContractImplementor session,
Object owner) throws HibernateException, SQLException
{
Object result = rs.getObject(names[0]);
if (result instanceof Timestamp) {
return ((Timestamp) result).toLocalDateTime();
}
return result;
}
@Override
public void nullSafeSet(PreparedStatement st,
Object value,
int index,
SharedSessionContractImplementor session) throws HibernateException, SQLException
{
if (value == null) {
st.setNull(index, sqlType);
}
if (value instanceof LocalDateTime) {
st.setTimestamp(index, Timestamp.valueOf((LocalDateTime) value));
}
if (value instanceof Long) {
st.setLong(index, (Long) value);
}
if (value instanceof String) {
st.setString(index, (String)value);
}
}
@Override
public Object deepCopy(Object value) throws HibernateException
{
return value;
}
@Override
public boolean isMutable()
{
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException
{
return Objects.toString(value);
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException
{
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException
{
return original;
}
}
和用法:
@Entity
public class Account
{
@Id
@Type(type = "com.example.hibernate.MyConverter")
@Column(name = "acc_id")
private Long id;
@Column(name = "acc_name", length = 50)
@Type(type = "com.example.hibernate.MyConverter")
private String name;
@Column(name = "acc_regdt")
@Type(type = "com.example.hibernate.MyConverter")
private LocalDateTime regDate;
}
关于java - JPA AttributeConverter 是否有可能知道有关 Entity 正在运行的任何信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60457002/