In a unidirectional relationship, only one entity has a relationship field or property that refers to the other. For example,
LineItem
would have a relationship field that identifies
Product
, but
Product
would not have a relationship field or property for
LineItem
. In other words,
LineItem
knows about
Product
, but
Product
doesn’t know which
LineItem
instances refer to it.
2020年12月6日完工。从此jpa多对多不再是阻碍
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class BossServiceServiceImpl implements BossServiceService {
@Autowired
private BossProductService bossProductService;
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class BossProductServiceImpl implements BossProductService {
@Autowired
private BossServiceService bossServiceService;
@ToString
// hashCode导致了栈溢出。所以不要用@Data
public class BossProductServiceDTO implements Serializable {
// ID
private Long id;
// 产品ID
private BossProductDTO bossProductEntity;
// 服务ID
private BossServiceDTO bossServiceEntity;
// 状态:0-下线,1-上线
private Integer status;
private Integer sequence;
循环依赖的解决方案
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class BossProductServiceImpl implements BossProductService {
// @Lazy注解注解的作用主要是减少springIOC容器启动的加载时间
// 当出现注入的循环依赖时,也可以添加@Lazy
@Lazy
@Autowired
private BossServiceService bossServiceService;
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class BossServiceServiceImpl implements BossServiceService {
@Lazy
@Autowired
private BossProductService bossProductService;
@OneToMany
@JoinColumn
//@JoinFormula("upper(substring(middle_name from 0 for 1))") call native SQL functions,可替代@JoinColumn
//@ColumnTransformer(read="decrypt(credit_card_num)", write="encrypt(?)") 对于rw的,还有@ColumnTransformer可以使用
// 排序 加到sql上,但后续Java层的处理可能导致前端收到的数据不是此顺序
@OneToMany
@JoinColumn
// 排序 加到sql上
@OrderBy(value = "sequence DESC, id ASC")
// 前端传的实体会按照此顺序排列,影响jpa级联更新的顺序
@OrderColumn("sequence DESC")
// 筛选 加到sql上,不太建议使用这个,因为及联更新时会略去 !=condition的,从而导致重复
@Where(clause = " status = 1 ")
// 注意类型用Set会重新排序。导入OrderBy无效。但级联更新正常
// 使用Set存取顺序不一致是因为使用的实现是HashSet,
private Set<UserRole> userRoles;
// 类型用List时,OrderBy正常。但级联更新有问题且返回的记录中有null。所以推荐使用Set
//private List<UserRole> userRoles;
public enum CascadeType {
PERSIST, // 持久化,新增支配方时,若带有关联关系,且被支配方已存在,会报detached entity passed to persist,若不存在会新增;更新支配方时,若关联的被支配方不存在,会insert,但insert的结果好像有问题。
MERGE, // 更新,新增支配方时,可带着关联关系(被支配方需存在);更新支配方时,除了关联关系,还可以对被支配方update (未传的被支配方字段 会被置空),且若被支配方不存在,会新增;
REMOVE, // 删除,删除支配方时,除了关联关系,还会将被支配方delete,这个慎用
REFRESH, // 刷新,获取最新的数据,因为在操作期间可能别的线程已改了数据并持久化了
DETACH; // 游离,删除支配方时,若其有与其相关的外键,会撤销所以相关的外键关联
private CascadeType() {
针对otm/mto 可以使用all。但针对mtm一定不能包含remove,推荐 merge,可加上refresh
@JsonIgnore // 视情况使用 @JsonBackReference或 @JsonManagedReference
@ManyToMany(mappedBy = "bossServices")
private List<BossProductEntity> bossProducts;
// 剔除关联的属性
@Override
public String toString() {
return "BossServiceEntity(id=" + this.getId() + ", code=" + this.getCode() + ", name=" + this.getName() + ")";