我遇到一个问题,我无法持久化或合并仅包含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() {
}
}
的ErrorMessage:
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
基本上,由于它只是一个ID和一个连接表,它在尝试持久化或合并Filter而没有任何字段时会死掉。
变通方法
将GenerationType.IDENTITY更改为GenerationType.AUTO。
- 唯一的骗局似乎是初始启动主键跳转50,然后它开始递增1。
将GenerationType更改为TABLE
- 这似乎是AUTO选择的。
向实体添加任意字段(即String test = &#34;测试&#34;。)
- 简单地让实体再增加一个字段使其持久化。但是,我不需要这个领域;我只想要一个集合
使关系双向化。
- 通过使关系双向化,表格会返回一个id(而不仅仅是id)。这仅适用,因为Filter由另一条记录拥有。
答案 0 :(得分:0)
一个好的解决方案会使代码双向化,正如您已经指出的那样,并使用&#34; @PrePersist&#34;注释,将id设置为&#34;规则&#34;对象。类似的东西:
Rule.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...
}
Filter.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...
}
FilterRepository.java
@Repository
public interface FilterRepository extends JpaRepository<Filter, Integer> { }
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);
}
}
上面的代码对我来说运行正常。
我希望这能解决你的问题。
干杯,尼古拉斯。
答案 1 :(得分:0)
我用4个不同的例子实现了你的问题:
只是ID
@Entity 公共类Case1实现了Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
// ... }
ID + 1字符串列
@Entity 公共类Case2实现了Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) 私人长身份; 私有字符串名称;
// ... }
一个。 with cascade = {CascadeType.ALL}
> @Entity
> public class Case3 implements Serializable {
>
> private static final long serialVersionUID = 1L;
>
> @Id
> @GeneratedValue(strategy = GenerationType.IDENTITY)
> private Long id;
> @OneToMany( fetch = FetchType.EAGER, orphanRemoval = true, cascade = { CascadeType.ALL } )
> private ArrayList<AdminUtilisateur> users = new ArrayList<>();
> // ...
>}
湾没有cascade = {CascadeType.ALL}
> @Entity
> public class Case4 implements Serializable {
>
> private static final long serialVersionUID = 1L;
>
> @Id
> @GeneratedValue(strategy = GenerationType.IDENTITY)
> private Long id;
>
> @OneToMany( fetch = FetchType.EAGER, orphanRemoval = true)
> private ArrayList<AdminUtilisateur> users = new ArrayList<>();
> // ...
>}
SQL查询结果很好(在PostgreSQL 9.3下测试)。 但是使用javax.persistence,我得到了不同的结果:
- 案例1:异常说明:要插入表[DatabaseTable(case1)]的字段列表为空。你必须至少定义 该表的一个映射。
- 案例2:工作正常。
- 案例3:本地异常堆栈:异常[EclipseLink-4002](Eclipse持久性服务 - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.DatabaseException内部 例外:org.postgresql.util.PSQLException:ERREUR:la valeur d'une clédupliquéeromptla contrainte unique«rule_code_key»
- 案例4:异常说明:要插入表[DatabaseTable(case4)]的字段列表为空。你必须至少定义 该表的一个映射。
醇>
案例1,3和&amp;的错误解释4很简单。
对于案例3,当您有 cascade = {CascadeType.ALL} 时,orm会在保留过滤器之前尝试保留规则一切都取决于需要,因为我的案例规则它已经存在。
案例1&amp; 4,您试图仅在表N°1上保留过滤器的ID,并在加入表上保留规则的ID +过滤器的ID。 这意味着过滤器只有ID 设计问题的同义词 =您必须为此表定义至少一个映射。