从一个视图映射具有嵌入式List的实体
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从一个视图映射具有嵌入式List的实体相关的知识,希望对你有一定的参考价值。
我试图使用spring-data-jpa实现简单的cqrs应用程序所以我有2个表用于编写 - 例如人和汽车(一个人可以有汽车列表)。我还使用了一个作为select * from person join car创建的视图...
所以来自的示例查询可以给出输出(一个用户有2辆车)
firstName|lastName| car_brand | car_model |
marek |k | tesla | s |
marek |k | mercdes | 190 |
现在我试图在jpa中映射这个视图,我试图嵌入列表
@Embeddable
class CarSnapshot {
private String carBrand;
private String carModel;
}
和
class PersonSnapshot {
private String firstName;
@Embedded // I tried also @OneToMany and ElementCollection
private Set<CarSnapshot> cars;
}
但它在我的情况下不起作用。你有任何想法如何解决它而且一对一的映射(人有最多一辆车)非常酷
答案
如果要使用嵌入类型,可以执行以下操作:
@Entity
@Table(name = "persons")
public class Person {
@Id
private Integer id;
@ElementCollection
@CollectionTable(name = "person_cars", joinColumns = @JoinColumn(name = "person_id"), foreignKey = @ForeignKey(name = "person_cars_persons_fk"))
private List<PersonCar> cars;
}
@Embeddable
class PersonCar {
@Column(length = 32, nullable = false)
private String brand;
@Column(length = 32, nullable = false)
private String model;
}
在这种情况下,您的db模式可以是这样的:
create table persons (
id integer not null constraint persons_pkey primary key,
);
create table person_cars (
person_id integer not null constraint person_cars_persons_fk references persons,
brand varchar(32) not null,
model varchar(32) not null,
constraint supported_docs_pkey primary key (doc_type, country_code)
);
(这是postgresql方言)
更多信息在这里:Hibernate User Guide - Collections of value types
更新
要将View映射到实体,您可以这样做:
@Data // It's Lombok annotation - c-tor, getters/setters etc.
@Entity
@Immutable
@IdClass(View.class)
@Subselect("select p.name as person_name, c.brand as car_brand, c.model as car_model from persons p join cars c on p.id = c.person_id")
public class View implements Serializable {
@Id private String personName;
@Id private String carBrand;
@Id private String carModel;
}
您可以使用带有视图名称的@Subselect
注释,而不是使用@Table
注释:
@Data
@Entity
@Immutable
@IdClass(View.class)
@Table(name = "my_view")
public class View implements Serializable {...}
工作demo。
更新2
后处理的解决方法......
DTO的:
@Value
public class PersonDto {
private String name;
private List<CarDto> cars = new ArrayList<>();
public PersonDto addCars(List<CarDto> cars) {
this.cars.addAll(cars);
return this;
}
}
@Value
public class CarDto {
private String brand;
private String model;
}
和ViewRepo
public interface ViewRepo extends JpaRepository<View, View> {
List<View> findByPersonName(String name);
default PersonDto getPersonByName(String personName) {
return new PersonDto(personName)
.addCars(findByPersonName(personName)
.stream()
.map(p -> new CarDto(p.getCarBrand(), p.getCarModel()))
.collect(Collectors.toList()));
}
}
以上是关于从一个视图映射具有嵌入式List的实体的主要内容,如果未能解决你的问题,请参考以下文章