JPA 与存储在不同数据库中的用户实体的多对多关系

JPA Many-to-Many Relationship with Users Entity Stored in a Different Database

TLDR;

我正在尝试创建与存储在不同数据库中的实体(用户)的关系,但不知道如何在 JPA 中执行此操作。

用例

我正在 Spring Boot/JPA 实施汽车服务。我创建了一个名为 Car 的 entity/table。一辆汽车可能有多个车主(用户),一个用户可能拥有多辆汽车。但是,User table 存储在单独的用户服务中。

由于这是一个多对多的关系,我觉得 JoinTable 比较合适。这里的问题是没有 User table 可以加入。我只需要将用户的 UUID 存储在连接 table 中,因此 GET 方法可以获取给定用户的所有汽车,或给定汽车的所有车主。

源代码

这是对 Car 实体的尝试。删除 ForeignKey 约束允许在连接 table 中创建条目,而不会由于缺少子 table.

而导致错误
@Data
@Entity
@Table(name = "car")
@EqualsAndHashCode(callSuper = true)
public class Car {
  @Id @GeneratedValue private UUID id;

  @ManyToMany
  @JoinTable(
      name = "car_owner",
      joinColumns = @JoinColumn(name = "car_id"),
      inverseJoinColumns = @JoinColumn(name = "user_id", insertable = false, updatable = false),
      foreignKey = @ForeignKey(name="user_id", value = ConstraintMode.NO_CONSTRAINT))
  private Set<User> users;

  private String model;
  private double price;
}

这是 User 实体 - JPA JoinTable 所必需的,但仅用于其 ID:

@Data
@Entity
@EqualsAndHashCode()
public class User {

  @Id private UUID id;

  @ManyToMany(mappedBy = "users")
  @JsonIgnore
  private Set<Car> cars;
}

将下面的模型发送到 JPA 存储库 save() 方法成功创建了连接中的汽车和条目 table:

{
  "model": "Ford Model T",
  "price": 850.00,
  "users": [
    {"id": "e048b593-aad9-4285-b3e6-49475ad9bd1d"},
    {"id": "1d0f7b1e-bc36-4b99-80a1-8835779598ca"}
  ]
}

问题陈述

但是,当我尝试检索属于特定用户 ID 的所有汽车时:

  @Query(
      value = "select * from car c inner join car_owner co on c.id = co.car_id where co.user_id = :userId",
      nativeQuery = true)
  List<Car> findByUserId(UUID userId);

我收到以下错误:

ERROR: column user1_.id does not exist Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: could not extract ResultSet; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not extract ResultSet (through reference chain: java.util.ArrayList[0]->Car["users"])]

如何读回给定用户的汽车列表?我会以错误的方式解决这个问题吗?我对其他实现持开放态度。

如@vincendep 所述,解决方案是删除 User 实体并将 Car 实体中的 users 属性 替换为以下内容:

@ElementCollection
@CollectionTable(name = "car_owner", joinColumns = @JoinColumn(name = "car_id"))
@Column(name = "user_id")
private Set<UUID> owners;

这仍将使用 car_owner 加入 table。可以使用以下模型创建具有多个用户的汽车:

{
  "model": "Ford Model T",
  "price": 850.00,
  "owners": [
    "32a7967d-8580-418d-b53a-221ed0c52222",
    "a708455c-c37c-4712-a7ce-59c9be5a5eb5"
  ]
}

您可以按用户 ID 查询汽车,如下所示(归功于@vincendep):

@Query(value = "from Car c where :ownerId member of c.owners")
List<Car> findByUserId(UUID ownerId);