java为什么@ManyToMany不能处理非主键列?
我有两个实体-用户和角色,它们具有以下关系:用户与自身有多个关系,与角色实体有多个关系
@Entity
public class UserEntity implements Serializable {
@Id
@Column(length = 12, columnDefinition = "BINARY(12)", name = "Id", unique = true)
private byte[] id;
@Column(name = "Login", unique = true, nullable = false)
private String login;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "User_Role",
joinColumns = { @JoinColumn(name = "UserLogin", referencedColumnName = "Login") },
inverseJoinColumns = { @JoinColumn(name = "RoleId", referencedColumnName = "Id") })
private Set<RoleEntity> roles;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "User_User",
joinColumns = { @JoinColumn(name = "UserParent") },
inverseJoinColumns = { @JoinColumn(name = "UserChild") })
private Collection<UserEntity> children;
...
}
和作用:
public class RoleEntity implements Serializable{
@Id
@Column(name = "Id", unique = true, nullable = false)
private String id;
...
}
DB设置的奇怪之处在于,用户与用户的关系是基于二进制Id键的
create table if not exists User_User (
UserParent binary,
UserChild binary
);
用户角色基于varchars
create table if not exists KNUser_UserRole (
UserLogin varchar,
RoleId varchar,
);
现在,当它运行时,用户关系运行良好。但是,当我尝试访问为角色返回的集合时,我得到一个ClassCastException:
java.lang.ClassCastException: **.entity.UserEntity cannot be cast to [B
at org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor.extractHashCode(PrimitiveByteArrayTypeDescriptor.java:41)
at org.hibernate.type.AbstractStandardBasicType.getHashCode(AbstractStandardBasicType.java:201)
at org.hibernate.type.AbstractStandardBasicType.getHashCode(AbstractStandardBasicType.java:205)
at org.hibernate.engine.spi.EntityKey.generateHashCode(EntityKey.java:114)
at org.hibernate.engine.spi.EntityKey.<init>(EntityKey.java:79)
at org.hibernate.internal.AbstractSessionImpl.generateEntityKey(AbstractSessionImpl.java:240)
at org.hibernate.engine.internal.StatefulPersistenceContext.getCollectionOwner(StatefulPersistenceContext.java:740)
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:1181)
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:800)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:651)
at org.hibernate.loader.Loader.doQuery(Loader.java:856)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2175)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:61)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:622)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:82)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1606)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:379)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:112)
at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180)
看起来用户实体正在转换为某个二进制(?)事情但是,用户之间的第一个关系可以正常工作,但是与另一个表的关系是错误的
我使用不同类型的不同列来连接表。允许这样做吗
另一件奇怪的事情是,当我将@Id注释切换到login字段时,角色工作正常,没有问题,但是当然,self-join-PersistentBag键是login而不是Id,这打破了关系,并且没有检索到结果。但是从UserEntity到“[B”的转换没有完成
同样,如果我将事情保留在示例中,并将Id类型更改为String(DB更改为varchar),它也会开始工作(当然,与User\u User表不一致)
我做错了什么?在这种情况下获取classcastexception的原因是什么?当我将byte[]更改为String时,它为什么工作?如果你有任何想法,请告诉我。我不想改变数据库的设计,因为这将导致大量的迁移和兼容性问题的客户端已经使用数据库
请注意:@Id必须位于Id二进制字段上,否则我将无法进行自连接(我无法两次指向不是主键的列,请参见:Is Hibernate ManyToMany self-join possible for non-key columns? getting mappingException)
干杯 亚当
# 1 楼答案
联接表中引用的列必须是唯一的条目,在这里,如果您在登录字段中放置@Id,则它可以正常工作,但当您将其更改为除@Id列以外的其他列时,您无法确定这些条目是否唯一。你能做的是
我认为应该行得通