这是一个谜题!:D
有没有办法强制 Hibernate 为实体加载集合而不首先加载整个实体?
让我更好地解释。我有一个这样注释的角色实体:
@Entity(name="Role")
@Table(name = "ROLES")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@javax.persistence.TableGenerator(
name="GENERATED_IDS",
table="GENERATED_IDS",
valueColumnName = "ID"
)
public abstract class Role implements Serializable {
private static final long serialVersionUID = 1L;
/**
* The id of this role. Internal use only.
*
* @since 1.0
*/
@Id @GeneratedValue(strategy = GenerationType.TABLE, generator="GENERATED_IDS")
@Column(name = "ROLE_ID")
protected long id;
/**
* Set of permissions granted to this role.
*
* @since 1.0
*/
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy="sourceRole")
protected Set<Permission> permissions = new HashSet<Permission>();
...
}
当我通过执行以下操作访问权限集合时:
Role role = ...
Set permissions = role.getPermission();
Hibernate 使用其 PersistentCollection 的子类之一包装返回的集合。然后我可以使用 Hibernate.initialize(permissions); 强制集合被初始化。
但是,我需要的是一种无需先加载角色实体即可完成相同任务的方法。我知道我需要权限集合的实体的 ID,以及集合的角色 (temp.pack.Role.permissions)。
有没有办法做到这一点?我希望避免访问数据库来检索角色对象的所有字段(很多!)只是为了获取集合并将它们全部丢弃。
我可以使用连接,但这使我可以访问权限对象本身,而不是我需要的实际 PersistentCollection 包装器。
我试过这个:
Session session = connectionInfoProvider.getSession();
// this is just "permissions", the collection field name
String attributeName = role.substring(role.lastIndexOf(".")+1, role.length());
// this is the Role class name, temp.pack.Role
String entityClassName = role.substring(0, role.lastIndexOf("."));
Class<?> roleClass = Class.forName(entityClassName);
Field collectionField = roleClass.getDeclaredField(attributeName);
collectionField.setAccessible(true);
Hibernate.initialize(collection);
但是没有用。我得到的集合只是一个普通的空集,没有加载任何内容。
我也试过这个:
Session session = connectionInfoProvider.getSession();
// this is just "permissions", the collection field name
String attributeName = role.substring(role.lastIndexOf(".")+1, role.length());
// this is the Role class name, temp.pack.Role
String entityClassName = role.substring(0, role.lastIndexOf("."));
Class<?> roleClass = Class.forName(entityClassName);
Field collectionField = roleClass.getDeclaredField(attributeName);
collectionField.setAccessible(true);
Object object = session.load(roleClass, id);
ProxyObject objectProxy = (ProxyObject)object;
LazyInitializer lazyInitializer = (LazyInitializer)objectProxy.getHandler();
Object objectImpl = lazyInitializer.getImplementation();
Object collection = collectionField.get(objectImpl);
Hibernate.initialize(collection);
但也没有工作,它失败了java.lang.IllegalArgumentException: unknown handler key
。
我也试过:
PersistenceContext context = ((SessionImplementor)currSession).getPersistenceContext();
CollectionPersister persister = ((SessionFactoryImplementor) sessFactory) .getCollectionPersister(role);
CollectionKey key = new CollectionKey(persister, id, EntityMode.POJO);
// collection - contains set containing actual data
PersistentCollection collection = context.getCollection(key);
但也失败了java.lang.IllegalArgumentException: unknown handler key
关于如何做到这一点的任何想法?