我想同时使用 JPA CASCADE 来持久化父级及其子级。父类 ( Filter
) 有一个复合键 ( PKFilter
)。Aldo,子类 ( FilterRule
) 有它的复合键 ( PKFilterRule
)。主键类带有注释,@Embeddable
它们被引用为@EmbeddedId
.
PK过滤器:
@Getter
@Setter
@Embeddable
@NoArgsConstructor
@AllArgsConstructor
@SuppressWarnings("JpaDataSourceORMInspection")
@EqualsAndHashCode
public class PkFilter implements Serializable {
@Column(name = "CUSTOMER_ID")
private int customerId;
@Column(name = "COMPANY_ID")
private int companyId;
@Column(name = "FILTER_ID")
private String filterId;
}
PKFilterRule:
@Getter
@Setter
@Embeddable
@NoArgsConstructor
@AllArgsConstructor
@SuppressWarnings("JpaDataSourceORMInspection")
@EqualsAndHashCode
public class PkFilterRule implements Serializable {
@Column(name = "CUSTOMER_ID")
private int customerId;
@Column(name = "COMPANY_ID")
private int companyId;
@Column(name = "FILTER_ID")
private String filterId;
@Column(name = "FILTER_RULE")
private String filterRule;
@Column(name = "FILTER_KEY")
private String filterKey;
}
筛选
@Getter
@Setter
@Entity
@EqualsAndHashCode
@Table( name = "IOND_FILTERS")
public class Filter {
@EmbeddedId
private PkFilter pkFilter;
@Column(name = "FILTER_TARGET")
private String filterTarget;
@Column(name = "FILTER_STATUS")
private String filterStatus;
@OneToMany(mappedBy = "filter", cascade = CascadeType.ALL)
private List<FilterRule> rules;
}
过滤规则
@Getter
@Setter
@Entity
@EqualsAndHashCode
@Table( name = "IOND_FILTERS_RULES")
public class FilterRule {
@EmbeddedId
private PkFilterRule pkFilterRule;
@MapsId
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "CUSTOMER_ID", referencedColumnName = "CUSTOMER_ID")
@JoinColumn(name = "COMPANY_ID", referencedColumnName = "COMPANY_ID")
@JoinColumn(name = "FILTER_ID", referencedColumnName = "FILTER_ID")
private Filter filter;
}
作为测试,我们尝试使用 FilterItem 创建一个 Filter,然后持久化 Filter 对象:
@RunWith(SpringRunner.class)
@SpringBootTest()
@TestPropertySource(locations = {"classpath:application-test.properties"})
public class ProductsApplicationTests {
@Autowired
private FilterRepository filterRepository;
@Test
@Transactional
@Commit
public void test() {
var uuid = UUID.randomUUID().toString();
//Cria um novo Filtro
var filter = new Filter();
filter.setPkFilter(
new PkFilter(208, 210, uuid)
);
filter.setFilterTarget("ET");
filter.setFilterStatus("EN");
//Adiciona alguns itens
var filterRule = new FilterRule();
filterRule.setPkFilterRule(
new PkFilterRule(208, 210, uuid, "RULE", "KEY")
);
filterRule.setFilter(filter);
filter.setRules(Collections.singletonList(filterRule));
filterRepository.saveAndFlush(filter);
}
}
而且,作为例外,我们得到:
Caused by: java.lang.IllegalArgumentException: Can not set int field api.products.domain.model.keys.PkFilterRule.companyId to api.products.domain.model.keys.PkFilter
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at java.base/jdk.internal.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:56)
at java.base/java.lang.reflect.Field.getInt(Field.java:594)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:62)
... 97 more
我们缺少什么?非常感谢!