如何持久保存仅包含集合和ID的实体?

Gui*_*rum 8 database postgresql persistence jpa openjpa

我有一个问题,我不能持久或合并一个只包含一个ID和一组其他对象的对象.如果我添加另一个字段,它将正常提交事务.此外,如果我将ID生成策略更改为AUTO,它也将起作用.

我团队的其他成员使用"IDENTITY"代替"AUTO",所以我希望与他们保持一致.他们的实体不仅仅是一个ID + Collection,所以它适用于他们.以下是我想要做的工作:

@Entity
public class Filter implements Serializable {

   @Id
   @GeneratedValue( strategy = GenerationType.IDENTITY )
   private Long id;

   @OneToMany( fetch = FetchType.EAGER, orphanRemoval = true, cascade = { CascadeType.ALL } )
   private ArrayList<Rule> rules = new ArrayList<>();

   public Filter() {

   }

}
Run Code Online (Sandbox Code Playgroud)

错误信息:

org.apache.openjpa.persistence.PersistenceException: ERROR: syntax error at or near ")"
  Position: 25 {prepstmnt 693640431 INSERT INTO Filter () VALUES ()} [code=0, state=42601]
FailedObject: middle.ware.Filter@630cd05
Run Code Online (Sandbox Code Playgroud)

本质上,因为它只是一个ID和一个连接表,它在尝试持久化或合并Filter而没有任何字段时就会死掉.

解决方法

  • 将GenerationType.IDENTITY更改为GenerationType.AUTO.

    - 唯一的骗局似乎是初始启动主键跳转50,然后它开始递增1.

  • 将GenerationType更改为TABLE

    - 这似乎是AUTO选择的.

  • 向实体添加任意字段(即String test ="test").

    - 简单地让实体再增加一个字段使其持久化.但是,我不需要这个领域; 我只想要一个收藏品

  • 使关系双向化.

    - 通过使关系成双向,表格会返回一个id(而不仅仅是id).这仅适用,因为Filter由另一条记录拥有.

E. *_*ira 0

正如您已经指出的,一个好的解决方案将使代码双向,并利用“@PrePersist”注释将 id 设置为“Rules”对象。就像是:

规则.java

@Entity
public class Rule implements Serializable {

    @Id
    @GeneratedValue( strategy = GenerationType.IDENTITY )
    private Long id;

    private String description;

    @ManyToOne
    private Filter filter;

    // getters, setters, equals, hashcode, toString...
}
Run Code Online (Sandbox Code Playgroud)

过滤器.java

@Entity
public class Filter implements Serializable {

    @Id
    @GeneratedValue( strategy = GenerationType.IDENTITY )
    private Long id;

    @OneToMany( fetch = FetchType.EAGER, orphanRemoval = true, cascade = { CascadeType.ALL }, mappedBy="filter" )
    private List<Rule> rules = new ArrayList<>();

    @PrePersist
    public void prePersist() {
        if (rules != null) {
            rules.forEach(item -> item.setFilter(this));
        }
    }

    // getters, setters, equals, hashcode, toString...
}
Run Code Online (Sandbox Code Playgroud)

FilterRepository.java

@Repository
public interface FilterRepository extends JpaRepository<Filter, Integer> { }
Run Code Online (Sandbox Code Playgroud)

AnUnitTest.java

@RunWith(SpringRunner.class)
@SpringBootTest
public class AnUnitTest {
    @Autowired
    private FilterRepository filterRepository;

    @After
    public void clearDatabase() {
        bodyPartRespository.deleteAll();

        filterRepository.deleteAll();
    }

    @Test
    public void testFilterRules() {
        Rule aRule = Rule.builder()
                .description("A")
                .build();
        Rule anotherRule = Rule.builder()
                .description("B")
                .build();

        Filter filter = Filter.builder()
                .rules(Arrays.asList(aRule, anotherRule))
                .build();

        filterRepository.saveAndFlush(filter);

        List<Filter> all = filterRepository.findAll();

        all.forEach(System.out::println);
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码对我来说运行良好。

我希望这能解决您的问题。

干杯,尼古拉斯。