当前位置: 首页 > 知识库问答 >
问题:

Quarkus Panache OneToMany关系在数据库中不持久化

师承弼
2023-03-14

我目前正在修补一个简单的HTTP资源。我的模型由多个“果实”的“树”组成。两者都继承自PanacheEntity。

    @Entity
    public class Tree extends PanacheEntity {
    public String name;

    @OneToMany(mappedBy = "tree", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    public List<Fruit> fruits = new ArrayList<>();
    }

水果

    @Entity
    public class Fruit extends PanacheEntity {

    public String name;
    public String color;
    public int cores;

    @ManyToOne
    @JsonbTransient
    public Tree tree;
    }

资源:

    import io.quarkus.hibernate.orm.rest.data.panache.PanacheEntityResource;

    public interface TreeResource extends PanacheEntityResource<Tree, Long> { }

这是我通过Swagger发送的帖子请求

{
  "name": "Apple Tree",
  "fruits": [
    {
      "color": "green",
      "cores": 3,
      "name": "Apple2"
    },
    {
      "color": "red",
      "cores": 4,
      "name": "Apple"
    }
  ]
}
{
  "id": 4,
  "fruits": [
    {
      "id": 5,
      "color": "green",
      "cores": 3,
      "name": "Apple2"
    },
    {
      "id": 6,
      "color": "red",
      "cores": 4,
      "name": "Apple"
    }
  ],
  "name": "Apple Tree"
}
[
  {
    "id": 1,
    "fruits": [],
    "name": "Oak"
  },
  {
    "id": 4,
    "fruits": [],
    "name": "Apple Tree"
  }
]

水果总是空的。检查postgres数据库会发现Fruit中的所有“tree_id”列都为NULL。我很确定这是一个初学者的问题,但是在检查了多个示例之后,我就是找不到我的代码有什么问题。

共有1个答案

洪鹏海
2023-03-14

我也遇到了同样的问题,并通过将parent对象设置为children解决了这个问题。我有Job和JobArgs项目要坚持。

    // ... somewhere in JobArg.java
    @JsonbTransient
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "job_id", foreignKey = @ForeignKey(name = "job_id_fk"))
    public Job job;
    @OneToMany(mappedBy = "job", cascade = CascadeType.ALL, orphanRemoval = true)
    public List<JobArg> arguments = new ArrayList<>();
    // ... somewhere in Job.java 
    // I used reactive-pgclient so my method return Uni<T>
    public void addArgument(final JobArg jobArg) {
        arguments.add(jobArg);
        jobArg.job = this;
    }
    public static Uni<Job> insert(final UUID userId, final JobDto newJob) {
        final Job job = new Job();
        //... map fields from dto ...
        newJob.getArguments().stream().map(arg -> {
            final JobArg jobArg = new JobArg();
            //... map fields from dto ...
            return jobArg;
        }).forEach(job::addArgument);
        
        final Uni<Void> jobInsert = job.persist();
        final Uni<UserAction> userActionInsert = UserAction.insertAction(type, job.id, userId, null);
        return Uni.combine().all().unis(jobInsert, userActionInsert).combinedWith(result -> job);
    }

这是来自Vlad Mihalcea博客的示例代码:用于双向映射:

@Entity(name = "Post")
@Table(name = "post")
public class Post {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String title;
 
    @OneToMany(
        mappedBy = "post",
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
    private List<PostComment> comments = new ArrayList<>();
 
    //Constructors, getters and setters removed for brevity
 
    public void addComment(PostComment comment) {
        comments.add(comment);
        comment.setPost(this);
    }
 
    public void removeComment(PostComment comment) {
        comments.remove(comment);
        comment.setPost(null);
    }
}
 
@Entity(name = "PostComment")
@Table(name = "post_comment")
public class PostComment {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String review;
 
    @ManyToOne(fetch = FetchType.LAZY)
    private Post post;
 
    //Constructors, getters and setters removed for brevity
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof PostComment )) return false;
        return id != null && id.equals(((PostComment) o).getId());
    }
 
    @Override
    public int hashCode() {
        return getClass().html" target="_blank">hashCode();
    }
}

在前面提到的映射中有几点需要注意:

子实体PostComment实现equals和hashCode方法。由于我们不能依赖自然标识符来进行相等性检查,因此我们需要使用实体标识符来代替equals方法。但是,您需要正确地进行操作,以便在所有实体状态转换中,相等性都是一致的,这也是hashCode必须是一个常量值的原因。因为我们依赖于removeComment的equality,所以在双向关联中重写子实体的equals和hashCode是一个很好的实践

.

 类似资料:
  • 我目前正在使用spring cloud gateway项目构建简单的api网关,计划将路由持久化到mongodb中,然后刷新,这样新的路由就可以使用了。我做了一些像这样简单的事情来获得我从蒙哥的路线。 我可以在数据库中创建新的路由,但我无法在飞行中刷新。

  • 我正在使用网络逻辑10.3。我正在尝试配置一个持久订阅,其中包含由 jdbc 存储(在 Oracle DB 中)支持的持久消息。我有一个主题,MDB 正在作为持久订阅者侦听该主题。在场景-1下:如果我发送消息,它会命中MDB。 在场景2中:我挂起了MDB,希望发送到主题的消息只要不被MDB(它是唯一注册的持久订阅者)使用,就会一直存在。但是当我向主题发送消息时,它短暂地出现在那里,然后就消失了(我

  • 我的应用程序有3个组件, 1) 一种面向用户的组件,接收请求并将其存储到数据库中。2)一个后端组件,从数据库中读取数据,进行处理并将其发送到外部系统。3) 存储用户输入的数据库 我如何测试流程是这样的:用户输入数据- 注意:我尝试使用ddl auto:update,但它不起作用。

  • 我的Spring主课:- 我的痛苦。属性 我在执行保存函数时的控制台输出:- 不要忘记我的集成测试类:=

  • 我正在尝试将嵌入式数据库derby与spring框架结合使用。我可以插入数据并读取它。除了数据库没有持久化之外,一切都很好。当我关闭应用程序并再次运行时,数据不存在。我猜数据库是再次创建的,但不知道为什么。 我的代码: 和Spring的输出日志是 create-db.sql内容是 解决方案:接受的答案指向正确的方向,但误差为db;create=true无法启动。然后,我查看了Netbeans ID

  • 在docker compose v3容器关闭并重新启动后,我很难持久化postgres数据。这似乎是一个常见的问题,但经过大量搜索,我一直无法找到有效的解决方案。 我的问题与此类似:如何使用卷在dockerized postgres数据库中持久化数据,但解决方案不起作用-因此请不要关闭。我将通过下面的所有步骤来复制这个问题。 这是我的docker-compose文件: 这是我调出并写入数据库后的终