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

Spring Data JPA-使用现有嵌套子对象持久化新对象

班经亘
2023-03-14

我确实有两个实体,称为学校和水平,具有多对多的关系。

@Data
@Entity
public class School {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "school_generator")
    @SequenceGenerator(name="school_generator", sequenceName = "school_seq", allocationSize=1)
    @Column(name = "school_id")
    private Long id;

    @NotBlank
    private String name;

    @NotBlank
    private String city;

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(
            name = "school_level",
            joinColumns = @JoinColumn(name = "school_id"),
            inverseJoinColumns = @JoinColumn(name = "level_id"))
    private Set<Level> levels = new HashSet<>();

}

@Data
@Entity
public class Level implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "level_generator")
    @SequenceGenerator(name = "level_generator", sequenceName = "level_seq", allocationSize = 1)
    @Column(name = "level_id")
    private Long id;

    @NotBlank
    @Column(nullable = false, unique = true)
    private String name;

}

我的SchoolControllerRest controller有一个create方法,它接受一个SchoolDTO(目前它的结构与实体相同)。

当我试图通过JPARepository保存方法保存时,会抛出一个包含以下消息的异常

"detached entity passed to persist: com.salimrahmani.adawat.domain.Level; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.salimrahmani.adawat.domain.Level",
    "trace": "org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist:

通过遍历每个级别Id来解决这个问题...使用JPA存储库方法getOne(它调用EntityManager.getReference)获取引用,然后加载正确的模型,然后成功持久化。

@PostMapping("/{id}/grades")
public ResponseEntity<SchoolDTO> addLevelToPackage(@PathVariable Long id, @RequestBody @Valid LevelDTO levelDTO) {
        return schoolService.findById(id)
                .map(school -> {
                    Level level = levelMapper.map(levelDTO);

                    if(level.getId() != null) {
                        level = levelService.getOne(level.getId());
                        school.getLevels().add(level);
                    } // else error

                    School saved = schoolService.save(school);

                    return ResponseEntity.ok(schoolMapper.map(saved));

                }).orElseGet(() -> ResponseEntity.notFound().build());
    }

我的问题是:这是在Spring数据中发布关联的“唯一”正确方式吗?或者,有没有更好的办法?

共有1个答案

辛渝
2023-03-14

AddLevelTopackage函数中,为什么要使用mapschoolService.findbyid(id).map..,如果我认为schoolService将只返回具有给定id的实体学校的一个实例。我想用下面的地图代替地图就足够了:

...
School theSchool = schoolService.findById(id);
Level theLevel = levelService.getOne(levelDTO.getId());
theSchool.getLevels().add(theLevel);
School saved = schoolService.save(theSchool);
return ResponseEntity.ok(schoolMapper.map(saved));
...
 类似资料:
  • 我有一个简单的JPA存储库,看起来如下所示: 和两个有一个单子映射的类,如下所示: . 现在,我知道我可以很容易地编辑和持久化一个像这样的用户实例: 但是,在没有指向实例的指针的上下文中,如何持久化实例,f.I.: 我可以只调用吗? 我是否需要自动连接另一个存储库()并在其上调用.save()?

  • Hibernate 认为持久化类(persistent class)新实例化的对象是瞬时(Transient)的。我们可通过将瞬时(Transient)对象与 session 关联而把它变为持久的(Persistent)。 DomesticCat fritz = new DomesticCat(); fritz.setColor(Color.GINGER); fritz.setSex('M');

  • 我有一个名为的类,它有一个狗的列表: 狗类有一个小狗列表: 当我试图创建一个新的人类,它有一只狗,狗又有一只小狗,并且我使用带有spring的Hibernate JPA存储库来保存人类时: 我得到以下错误: 但是,如果我用默认值创建人类,并用人类存储库保存他,它就能工作,并且保存了小狗。 我不明白为什么小狗没有自动保存,我也不想使用一个单独的存储库来保存小狗。当狗定义时,Hibernate不应该自

  • 问题内容: 每天都会通过Web服务导入数据。 我创建了一个pojo 的 新(临时)实例 ,该 实例 已通过JPA注释在hibernate中进行了映射。 我将来自Web服务的数据填充到临时实例中 我从数据库中加载要使用瞬时实例中的数据更新的持久对象。 我以某种方式将此瞬态实例与持久实例合并。如果持久对象在其字段之一上具有非null值,则不会被瞬态对象上的潜在null值覆盖。基本上,我不想丢失任何数据

  • 问题内容: 我有POJO类: 然后,我创建一张票证和一些地方: 现在,我想将其保存到数据库: 在MapperConfig.xml中,我这样写: 如何以自动模式保存 列表位置 ?MyBatis可以为我保存吗?还是我需要使用 foreach 手动进行迭代,然后手动插入每个 地方 ? 谢谢你的帮助。 问题答案: 即使MyBatis能够支持相反的方向(即在查询过程中使用嵌套选择或联接填充列表),也没有自动

  • 问题内容: 以下是对问题的后续问题: 我正在使用version 。如果所有成员变量都是基本类型,即使使用和注释,参数的名称与成员变量的名称不完全匹配,我也可以保留该对象。 但是,当我尝试保留包含其他对象的对象时,我得到了提示。我的问题: 这是错误,还是我做错了什么? 为了使我可以正确地持久化包含对象的对象,需要进行哪些更改? 。 我和班级如下: 更新:奇怪的是,将注释中的字符串更改为“属性”以外的