0

我们有带有存储 SpecialStrings 的遗留列的表。这些 SpecialStrings 不能为 NULL,而是等于 some SPECIAL_UNICODE_NULL

因此,要通过 JAX-WS 将实体发送回客户端,我们必须实现整个 Entity 包装器而不是 Entity 来发送它,或者将转换逻辑显式添加到 Entity get 方法。

我们想做的是使用我们自己的@LegacyString注解。

@Column(name="A_LEGACY_COLUMN")
@LegacyString
public String oneOfThenLegacyColumn;

然后在默认的实体侦听器中@PostLoad,我们将使用适当的转换将所有 @LegacyString 字段转换为常规字符串。

但这种解决方案的问题在于,在加载后修改实体后,实体被视为已更改,实体管理器将尝试将其更新到数据库。当然我可以使用@PreUpdate方法来恢复更改。但我不确定这是否会阻止实体进行真正的更新。

所以问题是:如何通过自己的注释更改实体 Bean 值视图?

PS 我对 ClassLoader 进行了一些研究,我将考虑通过添加加载时间的变化来进行变体。但是我找不到应用程序服务器类加载器案例的合理示例。

4

1 回答 1

2

在 Hibernate 中,您可以通过创建自己的 org.hibernate.usertype.UserType.

public class SpecialStringUserType implements UserType {

  private static final int[] SQL_TYPES = { Types.VARCHAR };

  public int[] sqlTypes() {
    return SQL_TYPES;
  }

  public Class returnedClass() {
    return String.class;
  }

  public boolean equals(Object x, Object y) 
      throws HibernateException {
    if (x == y) {
      return true;
    } else if (x == null || y == null) {
      return false;
    } else {
      return x.equals(y);
    }
  }

  public Object nullSafeGet(ResultSet resultSet, 
      String[] names, Object owner)
      throws HibernateException, SQLException {
    String result = resultSet.getString(names[0]);
    if ("SPECIAL_UNICODE_NULL".equals( result )) {
       return null;
    }
    return result;
  }

  public void nullSafeSet(PreparedStatement statement, 
      Object value, int index)
      throws HibernateException, SQLException {
    if (value == null) {
      statement.setString(index, "SPECIAL_UNICODE_NULL");
    } else {
      statement.setString(index, value);
    }
  }

  public Object deepCopy(Object value) throws HibernateException {
    return value;
  }

  public boolean isMutable() {
    return false;
  }
}

不要使用您自己的@LegacyString注释,而是执行以下操作:

@Column(name="A_LEGACY_COLUMN")
@Type( type = "SpecialStringUserType" )
public String oneOfThenLegacyColumn;
于 2009-07-02T04:04:59.830 回答