Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java hibernate实体:允许通过id和对象本身设置相关对象_Java_Hibernate_Foreign Keys - Fatal编程技术网

java hibernate实体:允许通过id和对象本身设置相关对象

java hibernate实体:允许通过id和对象本身设置相关对象,java,hibernate,foreign-keys,Java,Hibernate,Foreign Keys,我有一个Java类,它也是一个Hibernate实体: @Entity @Table(name = "category") public class Category { @ManyToOne @JoinColumn(name="parent_id") private Category parent; public Category getParent() { return parent; } public void setP

我有一个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);
}
public void createCategory(int parent_id,字符串名称,CategoryType类型){
类别=新类别();
类别.集合名(名称);

//category.setParent(?);Hibernate为此场景提供了一个名为(相当令人困惑的)
Session.load()的方法

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

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

category.setParent(session.load(Category.class, parent_id));
请注意,此代码不会使用给定id检查是否存在
Category
。但是,如果您的DB架构中存在外键约束,则传入无效id时会出现约束冲突错误


此方法的JPA等价物称为
EntityManager.getReference()

您可以定义lazy init

@ManyToOne(fetch=FetchType.LAZY)

猜测列是可为空的,因此在没有父(根)的情况下保存类别不是问题。

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

Constructor c=entityClass.getDeclaredConstructor();
c、 setAccessible(true);
S instance=c.newInstance();
Fields.set(实例“id”,entityId.getId());
Fields.set(实例“version”,entityId.getVersion());
返回实例;
我们可以使用这种方法,因为我们不使用延迟加载,而是拥有GUI上使用的实体的“视图”。这允许我们摆脱Hibernate用于填充所有急切关系的所有连接。视图始终具有实体的id和版本。因此,我们可以通过创建一个显示为H的对象来填充引用伊比利亚酸盐不是暂时的


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

为什么不试试呢?是的,它可能会工作。@Magnustingdahl我不知道如何进行注释映射。。。这并没有回答问题。目标恰恰是创建一个具有父级的类别。我这里有一个问题:我的架构设计假设我使用的是BO/DAO(业务对象/数据访问对象)。DAO是hibernate级别,它包含hibernate会话。BO(我的第二个代码段中的一个)甚至不知道诸如hibernate会话之类的东西存在。但是-根据您的代码-我必须使用
会话。load
。我应该在我的体系结构中更改什么?如果我希望我的Category BO类是泛型的,也许我应该为该类别提供
setParentId
方法,在BO中调用它并在DAO级别上处理它l-你怎么看?我认为最好的选择是在DAO中添加一个对应的方法,比如
Category to reference(long categoryId)
。所以它或多或少是-DAO,请给我一个对父类对象的惰性引用,稍后您将使用它(我现在只需要它).我不知道你是怎么做到的,但我想你知道的。”对吧?是的。这会让你的DAO抽象在某种程度上泄漏,但在这种情况下这是不可避免的。
        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;