java hibernate entity:允许通过id和object本身设置相关对象
我有一个以下的Java类,它也是一个Hibernate实体:
@Entity @Table(name = "category") public class Category { @ManyToOne @JoinColumn(name="parent_id") private Category parent; public Category getParent() { return parent; } public void setParent(Category parent) { this.parent = parent; }
该类别表示类别树中的节点。 我正在实现一个允许CRUD类别的Web服务。 例如,接口能够创建类别树节点,并将类别id作为参数传递。
我只想创建一个新的Category对象并将其持久保存到数据库中而不需要获取父对象。 我的数据提供程序类如下所示:
public void createCategory(int parent_id, String name, CategoryType type) { Category category = new Category(); category.setName(name); // category.setParent(?); <- I don't have this object here // category.setParentId(id); <- but I do have the id category.setType(type); this.categoryDao.save(category); }
我的问题是:如果假设我不会调用hibernate来为我取父(这会很愚蠢),我该怎么做才能创建一个带有parent_id集的新Category对象? 我可以为Category类提供setParentId / getParentId方法吗? 它有什么hibernate注释?
Hibernate为这种情况提供了一种称为(相当令人困惑的) Session.load()
的方法。
Session.load()
返回一个具有给定标识符的惰性代理,而不查询数据库(如果具有给定标识符的对象已经在当前Session
加载,则它返回一个对象本身)。
您可以使用该代理初始化要保存的实体中的关系:
category.setParent(session.load(Category.class, parent_id));
请注意,此代码不会检查具有给定id的Category
存在性。 但是,如果数据库模式中有外键约束,则在传入无效ID时会出现约束违规错误。
相当于此方法的JPA称为EntityManager.getReference()
。
还有一个问题的解决方案 – 使用您想要引用的实体的默认构造函数,并设置id和version(如果它是版本化的)。
Constructor c = entityClass.getDeclaredConstructor(); c.setAccessible(true); S instance = c.newInstance(); Fields.set(instance, "id", entityId.getId()); Fields.set(instance, "version", entityId.getVersion()); return instance;
我们可以使用这样的方法,因为我们不使用延迟加载,而是具有在GUI上使用的实体的“视图”。 这允许我们摆脱Hibernate用来填充所有渴望关系的所有连接。 视图始终具有实体的ID和版本。 因此,我们可以通过创建一个Hibernate看起来不是瞬态的对象来填充引用。
我尝试了这种方法和session.load()的方法。 他们都工作得很好。 我看到我的方法有一些优点,因为Hibernate不会泄漏其代理中其他地方的代理。 如果没有正确使用,我只会得到NPE而不是’no session bound to thread’exception。
您可以定义延迟初始化
@ManyToOne(fetch=FetchType.LAZY)
猜这个列是可空的,所以没有父级(root)保存类别不是问题
- hibernate-validator中的exception。 嵌套exception是java.lang.NoClassDefFoundError:ConfigurationImpl
- UnexpectedRollbackException – 完整的场景分析
- 使用Spring HibernateDaoSupport进行延迟加载?
- 使用@IdClass和*嵌套*复合主键限制JPA 1.0?
- 为什么即使在Spring服务类的第二种方法中传播= Propagation.REQUIRES_NEW时,事务也会回滚?
- 如何在多对多关系中使用hibernate和JPA删除孤立实体?
- Hibernate升级到5.2 – 创建会话工厂并替换PersistentClass以获取实体类属性
- 在Hibernate中使用saveOrUpdate()创建新记录而不是更新现有记录
- org.hibernate.hql.internal.ast.QuerySyntaxException:意外令牌:*靠近第1行