首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >java hibernate entity:允许根据id和对象本身设置相关对象

java hibernate entity:允许根据id和对象本身设置相关对象
EN

Stack Overflow用户
提问于 2013-04-17 01:52:12
回答 3查看 6.9K关注 0票数 14

我有一个下面的Java类,它也是一个Hibernate实体:

代码语言:javascript
运行
复制
@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类别的CRUD服务。例如,该接口能够创建类别树节点,并将类别id作为参数进行传递。

我只想创建一个新的Category对象,并将其持久化到数据库中,而不获取父对象。我的数据提供程序类如下所示:

代码语言:javascript
运行
复制
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类提供setParentId/getParentId方法?它会有什么hibernate注解?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-17 02:09:02

Hibernate为这个场景提供了一个叫做Session.load()的方法(非常令人困惑)。

Session.load()返回一个具有给定标识符的惰性代理,而不查询数据库(如果具有给定标识符的对象已经加载到当前Session中,则它本身返回一个对象)。

您可以使用该代理来初始化要保存的实体中的关系:

代码语言:javascript
运行
复制
category.setParent(session.load(Category.class, parent_id));

请注意,此代码不会检查是否存在具有给定id的Category。然而,如果您的DB模式中有一个外键约束,那么当传入无效的id时,您将得到一个违反约束的错误。

与此方法等效的JPA称为EntityManager.getReference()

票数 21
EN

Stack Overflow用户

发布于 2014-01-14 20:38:45

还有一个解决方案-使用你想要引用的实体的默认构造函数,并设置id和版本(如果它是版本化的)。

代码语言:javascript
运行
复制
        Constructor<S> 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和版本。因此,我们可以通过创建一个看起来像是休眠的对象来填充引用。

我尝试了这种方法和使用session.load()的方法。它们都工作得很好。我在我的方法中看到了一些好处,因为Hibernate不会在代码中的其他地方泄漏它的代理。如果没有正确使用,我将只获取NPE,而不是“没有绑定到线程的会话”异常。

票数 1
EN

Stack Overflow用户

发布于 2013-04-17 02:11:41

您可以定义lazy init

代码语言:javascript
运行
复制
@ManyToOne(fetch=FetchType.LAZY)

我猜这个列是可以为空的,所以保存没有父目录(根目录)的Category是没有问题的

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16043761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档