-
实体类
一对多关系,并由Many处去管理管理关系
-
One处的实体类
@Entity @Data public class ClientApp { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToMany(targetEntity = ClientAppModule.class,mappedBy ="clientApp" ) private List modules=List.of(); }
-
Many处的实体类
@Data @Entity @IdClass(Key.class) public class ClientAppModule implements Serializable { @Id private Long authId; //权限id @ManyToOne @Id @JsonIgnoreProperties("modules") @JoinColumn(name = "client_app_id") private ClientApp clientApp;
private LocalDateTime expiredTime; private ClientAppModuleStatus status;}
-
再格外加一个idClass类 查询的时候需要
@Data @NoArgsConstructor public class Key implements Serializable { private Long authId; //权限id private ClientApp clientApp; }
-
数据层操作层
-
One处的Repository
public interface ClientAppRepository extends JpaRepository<ClientApp, Long> { }
-
Many处的Repository
public interface ClientAppModuleRepository extends JpaRepository<ClientAppModule, Key> { }
-
操作方法
-
保存One处的时候 由于关联关系由Many处去管理,所以非常简单
@Test public void create(){ ClientApp clientApp = new ClientApp(); /* ..业务赋值..*/ clientAppRepository.save(clientApp); }
注意为什么要将保存Many处的对象单独来说 ,因为其 "复合主键成员为关联对象"的原因和普通的关系对象保存不一样。
如果是普通的一对多关联,你可以下下面操作
final ClientAppModule clientAppModule = new ClientAppModule();
clientAppModule.setAuthId(1L);
//方法一:
ClientApp clientApp = clientAppRepository.findById(1L).get();
//方法二:
//clientApp = new ClientApp();clientApp.setId(1L);
//设置关联关系
clientAppModule.setClientApp(clientApp);
clientAppModuleRepository.save(clientAppModule);
但是!!如果像一般的一对多去使用JpaRepository#save保存时 他会提示你
Cannot convert value of type 'java.lang.Long' to required type 'com.example.springdemo.entity.ClientApp' for property 'clientApp': no matching editors or conversion strategy found
由于鄙人愚笨 就只能 不使用SpringJpa,而使用EntityManager#persist、EntityManager#merge
-
注意如果你传给many的One不是关联实体 就必要使用merge方法
final ClientAppModule clientAppModule = new ClientAppModule(); clientAppModule.setAuthId(1L); ClientApp clientApp=clientAppRepository.findById(1L).get(); clientAppModule.setClientApp(clientApp); entityManager.persist(clientAppModule); -
而persist对one是不是持久化对象,都无所谓
final ClientAppModule clientAppModule = new ClientAppModule(); clientAppModule.setAuthId(1L); ClientApp clientApp=null; //方法一: //clientApp = clientAppRepository.findById(1L).get(); //方法二: clientApp = new ClientApp(); clientApp.setId(1L); //设置关联关系 clientAppModule.setClientApp(clientApp); entityManager.merge(clientAppModule);
查询问题
和平常的一样 ,使用SpringJpa查询就行。
final Key id = new Key();
id.setAuthId(1L);
final ClientApp clientApp = new ClientApp();clientApp.setId(1L);
id.setClientApp(clientApp);
final ClientAppModule clientAppModule = clientAppModuleRepository.findById(id).get();
修改问题
调用save的时候还是报上面的错误
-
你可以使用Jpa查询出来的对象是持久态,来操作。事务完成之后会自动提交(一定要在事务中)
final Key id = new Key(); id.setAuthId(1L); final ClientApp clientApp = new ClientApp();clientApp.setId(1L); id.setClientApp(clientApp); final ClientAppModule clientAppModule = clientAppModuleRepository.findById(id).get(); clientAppModule.setStatus(ClientAppModuleStatus.ENABLE); //clientAppModuleRepository.save(clientAppModule); 会报错
-
使用EntityManager#persist、EntityManager#merge.注意事项和保存的时候一样
final ClientAppModule clientAppModule = new ClientAppModule(); clientAppModule.setAuthId(1L); final ClientApp clientApp = new ClientApp(); clientApp.setId(1L); // final ClientAppModule clientAppModule = clientAppModuleRepository.findById(id).get(); clientAppModule.setClientApp(clientApp); clientAppModule.setStatus(ClientAppModuleStatus.STOP); entityManager.merge(clientAppModule);