java - 带有转换器问题的休眠 UserCollectionType
问题描述
如果我们为@ElementCollection 使用Converter,其中collection 是默认列表、集合或映射,那么这将按预期工作。
public abstract class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ElementCollection(targetClass = State.class, fetch = FetchType.EAGER)
@CollectionTable(name = "states")
@Column(name = "state")
@Access(value = AccessType.PROPERTY)
@Convert(converter = StateAttributeConverter.class)
private Set<State> states;
}
public enum State {
FIRST(10), SECOND(5), THIRD(2);
private final int value;
public static State ofValue(int value) {
for(State state : values()) {
if(State.getValue() == value) {
return state;
}
}
throw new IllegalArgumentException("");
}
State(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
@Converter
public class StateAttributeConverter implements AttributeConverter<State, Integer> {
private static final State[] allStates = State.values();
@Override
public Integer convertToDatabaseColumn(State state) {
return state.getValue();
}
@Override
public State convertToEntityAttribute(Integer integer) {
return State.ofValue(integer);
}
}
在表中,我观察到值 10、5 和 2(根据需要)
但是,如果我实现自定义状态集合并为其实现org.hibernate.UserCollectionType,那么转换器将被忽略。对于标准集合(List 或 Set),使用了类似的实现(org.hibernate.SetType,org.hibernate.ListType)并且在它们中转换成功。
我的收藏和 UserCollectionType 实现:
public class States implements Set<State> {
private EnumSet<State> states;
public static States full() {
return new States(Set.of(State.values()));
}
public static States empty() {
return new States(new HashSet<>());
}
public States(Set<State> states) {
this.states = states.isEmpty() ? EnumSet.noneOf(State.class) : EnumSet.copyOf(states);
}
States() { // For JPA
this.states = EnumSet.noneOf(State.class);
}
@Override
public Iterator<State> iterator() {
return this.states.iterator();
}
@Override
public int size() {
return this.states.size();
}
/* set methods */
}
public class StatesType implements UserCollectionType {
@Override
public PersistentCollection instantiate(SharedSessionContractImplementor session, CollectionPersister persister) throws HibernateException {
return new PersistentSet(session);
}
@Override
public PersistentCollection wrap(SharedSessionContractImplementor session, Object set) {
return new PersistentSet(session, (Set)set);
}
@Override
public Iterator getElementsIterator(Object collection) {
return ((States)collection).iterator();
}
@Override
public boolean contains(Object collection, Object entity) {
return ((States)collection).contains((State)entity);
}
@Override
public Object indexOf(Object collection, Object entity) {
throw new UnsupportedOperationException("");
}
@Override
public Object replaceElements(Object original, Object target, CollectionPersister persister, Object owner, Map copyCache, SharedSessionContractImplementor session) throws HibernateException {
States result = (States)target;
result.clear();
result.addAll((States)original);
return result;
}
@Override
public Object instantiate(int i) {
return States.empty();
}
}
在这种情况下,转换器将被忽略,并且在表中我看到了 State (Enum) 的ordinal()的值- 0、1 和 2。
@ElementCollection(targetClass = State.class, fetch = FetchType.EAGER)
@CollectionTable(name = "states")
@Column(name = "state")
@Access(value = AccessType.PROPERTY)
@CollectionType(type = "org.my.package.StatesType")
@Convert(converter = StateAttributeConverter.class)
private States states;
如何让UserCollectionType使用转换器?
解决方案
推荐阅读
- xamarin - 在 Apple Silicon M1 Mac 上运行的 iOS 应用程序的默认应用程序中打开文件
- html - 如何让禁用选项在选择 html 时变为粗体和黑色?
- python - 如何将此for循环转换为while循环(Python)?
- windows - 为什么使用“ls -a”时不断弹出错误?
- bigcommerce - 为什么产品集合页面 bigcommerce 上的一张缩略图比其他缩略图大?
- jinja2 - 将查询结果存储在变量中(jinja)
- java - 无法为事务打开 JDBC 连接;嵌套异常是 java.sql.SQLTransientConnectionException
- html - 我如何自动完成关闭
- c - 通过指针与数组写入字符串文字
- r - 加载两个库的问题