在@ManytoMany 关系和具有额外列的查找表的情况下,无法检索 Spring HATEOAS 嵌入的资源对象 [英] Unable to retrieve Spring HATEOAS embedded resource object in case of @ManytoMany relationship and lookup table with extra column
问题描述
我无法检索嵌入式.我正在使用 Spring boot、spring data rest 和 spring JPA.我在数据库中有 3 个表
- 用户
- 能力
- user_competency(带有额外列的连接/复合表)
用户
@Entity@Table(name = "\"user\"", schema = "public")@JsonIdentityInfo(生成器 = ObjectIdGenerators.IntSequenceGenerator.class,属性 = "用户 ID")公共类用户实现 java.io.Serializable {私人长用户ID;@Id @GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "user_id", unique = true, nullable = false)公共长 getUserId() {返回 this.userId;}public void setUserId(Long userId) {this.userId = 用户 ID;}私有集<UserCompetency>userCompetency = new HashSet(0);@OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.ALL},mappedBy = "user")公共集获取用户能力(){返回 this.userCompetencies;}public void setUserCompetencies(Set userCompetencies) {this.userCompetencies = userCompetencies;}}**能力**@实体@Table(name = "competency", schema = "public")@JsonIdentityInfo(生成器 = ObjectIdGenerators.IntSequenceGenerator.class,属性 = "能力 ID")公共类 Competency 实现了 java.io.Serializable {私人长期能力Id;私有集<UserCompetency>userCompetency = new HashSet(0);@Id @GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "competency_id", unique = true, nullable = false)公共长 getCompetencyId() {返回 this.competencyId;}公共无效setCompetencyId(长能力Id){this.competencyId = 能力 ID;}@OneToMany(fetch = FetchType.LAZY,mappedBy = "能力")公共集获取用户能力(){返回 this.userCompetencies;}public void setUserCompetencies(Set userCompetencies) {this.userCompetencies = userCompetencies;}}
用户能力
@Entity@Table(name = "user_competency", schema = "public")@JsonIdentityInfo(生成器 =ObjectIdGenerators.IntSequenceGenerator.class,属性 = "id")公共类 UserCompetency 实现 java.io.Serializable {私有 UserCompetencyId id;私人级别;私人用户用户;私人能力;@EmbeddedId@AttributeOverrides({@AttributeOverride(name = "competencyId", column = @Column(name = "competency_id", nullable = false)),@AttributeOverride(name = "userId", column = @Column(name = "user_id", nullable = false)) })公共 UserCompetencyId getId() {返回 this.id;}public void setId(UserCompetencyId id) {this.id = id;}@ManyToOne(fetch = FetchType.EAGER)@JoinColumn(name = "level_id")公共级别 getLevel() {返回 this.level;}public void setLevel(Level level) {this.level = 级别;}@ManyToOne(fetch = FetchType.EAGER)@JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)公共用户 getUser() {返回 this.user;}公共无效设置用户(用户用户){this.user = 用户;}@ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)@JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)公共能力 getCompetency() {返回 this.competency;}公共无效setCompetency(能力能力){this.competency = 能力;}}
UserCompetencyId
@Embeddable公共类 UserCompetencyId 实现 java.io.Serializable {私人长期能力Id;私人长用户ID;公共 UserCompetencyId() {}public UserCompetencyId(长能力Id,长用户ID){this.competencyId = 能力 ID;this.userId = 用户 ID;}@Column(name = "competency_id", nullable = false)公共长 getCompetencyId() {返回 this.competencyId;}公共无效setCompetencyId(长能力Id){this.competencyId = 能力 ID;}@Column(name = "user_id", nullable = false)公共长 getUserId() {返回 this.userId;}public void setUserId(Long userId) {this.userId = 用户 ID;}公共布尔等于(对象其他){如果((这个==其他))返回真;如果((其他==空))返回假;if (!(other instanceof UserCompetencyId))返回假;UserCompetencyId castOther = (UserCompetencyId) other;返回 (this.getCompetencyId() == castOther.getCompetencyId()) &&(this.getUserId() == castOther.getUserId());}}
UserCompetencyRepository
公共接口 UserCompetencyRepository 扩展 JpaRepository{}
pom.xml
<modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>Demo</artifactId><version>0.0.1-SNAPSHOT</version><包装>战争</包装><name>Demo</name><description>Demo api </description><父母><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.2.RELEASE</version><相对路径/><!-- 从存储库中查找父级 --></父母><属性><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></属性><依赖项><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></依赖><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></依赖><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId></依赖><依赖><groupId>org.springframework.data</groupId><artifactId>spring-data-rest-hal-browser</artifactId></依赖><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-hateoas</artifactId></依赖><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></依赖><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></依赖><依赖><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><scope>运行时</scope></依赖><依赖><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></依赖><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><范围>提供</范围></依赖><依赖><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>运行时</scope></依赖><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><范围>测试</范围></依赖><依赖><groupId>org.springframework.restdocs</groupId><artifactId>spring-restdocs-mockmvc</artifactId><范围>测试</范围></依赖><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></依赖><依赖><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></依赖><依赖><groupId>org.springframework.data</groupId><artifactId>spring-data-rest-webmvc</artifactId></依赖></依赖项><构建><插件><插件><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></插件></plugins></build></项目>
并且我想使用 URI 执行 GET,它返回我嵌入的对象并且无法获取对象属性的实际值
获取
如何获取需要 userId=8 帮助的 User 和 Competency 对象的属性值
在实施建议的投影问题后仍未解决,这里是屏幕截图
一种方法是使用投影,例如:
@Projection(name = "edit" , types = Employee.class)公共接口 EditEmployeeProjection {字符串 getFirstName();String getLastName();设置<项目>获取项目();}
这样,项目列表将嵌入到
已编辑 2我使用的代码:
能力.class
@Entity@Table(name = "competency", schema = "public")@JsonIdentityInfo(生成器 = ObjectIdGenerators.IntSequenceGenerator.class,属性 = "能力 ID")公共类 Competency 实现了 java.io.Serializable {@Id @GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "competency_id", unique = true, nullable = false)私人长期能力Id;@OneToMany(fetch = FetchType.LAZY,mappedBy = "能力")私人列表<UserCompetency>userCompetencies = new ArrayList<>();
用户能力.class
@Entity@Table(name = "user_competency", schema = "public")@JsonIdentityInfo(生成器 = ObjectIdGenerators.IntSequenceGenerator.class,属性 = "id")公共类 UserCompetency 实现 java.io.Serializable {@EmbeddedId@AttributeOverrides({@AttributeOverride(name = "competencyId", column = @Column(name = "competency_id", nullable = false)),@AttributeOverride(name = "userId", column = @Column(name = "user_id", nullable = false)) })私有 UserCompetencyId id;@ManyToOne(fetch = FetchType.EAGER)@JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)私人用户用户;@ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)@JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)私人能力;
UserCompetencyId.class
@Embeddable公共类 UserCompetencyId 实现 java.io.Serializable {@Column(name = "competency_id", nullable = false)私人长期能力Id;@Column(name = "user_id", nullable = false)私人长用户ID;
UserCompetencyRepository.class
@RepositoryRestResource(excerptProjection = UserCompetencyProjection.class)公共接口 UserCompetencyRepository 扩展 JpaRepository{实现此后,在我的情况下,它无法显示所需的 jason [![在此处输入图像描述][2]][2]
I am unable to retrieve embedded .I am using Spring boot ,spring data rest and spring JPA. I have 3 tables in data base
- user
- competency
- user_competency (join/composite table with extra column)
User
@Entity
@Table(name = "\"user\"", schema = "public")
@JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "userId")
public class User implements java.io.Serializable {
private Long userId;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id", unique = true, nullable = false)
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
private Set<UserCompetency> userCompetencies = new HashSet<UserCompetency>(0);
@OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.ALL}, mappedBy = "user")
public Set<UserCompetency> getUserCompetencies() {
return this.userCompetencies;
}
public void setUserCompetencies(Set<UserCompetency> userCompetencies) {
this.userCompetencies = userCompetencies;
}
}
**Competency**
@Entity
@Table(name = "competency", schema = "public")
@JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "competencyId")
public class Competency implements java.io.Serializable {
private Long competencyId;
private Set<UserCompetency> userCompetencies = new HashSet<UserCompetency>(0);
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "competency_id", unique = true, nullable = false)
public Long getCompetencyId() {
return this.competencyId;
}
public void setCompetencyId(Long competencyId) {
this.competencyId = competencyId;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "competency")
public Set<UserCompetency> getUserCompetencies() {
return this.userCompetencies;
}
public void setUserCompetencies(Set<UserCompetency> userCompetencies) {
this.userCompetencies = userCompetencies;
}
}
UserCompetency
@Entity
@Table(name = "user_competency", schema = "public")
@JsonIdentityInfo(
generator =ObjectIdGenerators.IntSequenceGenerator.class,
property = "id")
public class UserCompetency implements java.io.Serializable {
private UserCompetencyId id;
private Level level;
private User user;
private Competency competency;
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "competencyId", column = @Column(name = "competency_id", nullable = false)),
@AttributeOverride(name = "userId", column = @Column(name = "user_id", nullable = false)) })
public UserCompetencyId getId() {
return this.id;
}
public void setId(UserCompetencyId id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "level_id")
public Level getLevel() {
return this.level;
}
public void setLevel(Level level) {
this.level = level;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
@ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)
public Competency getCompetency() {
return this.competency;
}
public void setCompetency(Competency competency) {
this.competency = competency;
}
}
UserCompetencyId
@Embeddable
public class UserCompetencyId implements java.io.Serializable {
private Long competencyId;
private Long userId;
public UserCompetencyId() {
}
public UserCompetencyId(Long competencyId, Long userId) {
this.competencyId = competencyId;
this.userId = userId;
}
@Column(name = "competency_id", nullable = false)
public Long getCompetencyId() {
return this.competencyId;
}
public void setCompetencyId(Long competencyId) {
this.competencyId = competencyId;
}
@Column(name = "user_id", nullable = false)
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof UserCompetencyId))
return false;
UserCompetencyId castOther = (UserCompetencyId) other;
return (this.getCompetencyId() == castOther.getCompetencyId()) && (this.getUserId() == castOther.getUserId());
}
}
UserCompetencyRepository
public interface UserCompetencyRepository extends JpaRepository<UserCompetency, UserCompetencyId> {
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>Demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Demo</name>
<description>Demo api </description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
and I want to perform GET using URI,it return me embedded object and cannot get real value of objects attributes
GET http://localhost:8080/userCompetencies
How Can I get attribute values of User and Competency object where userId=8 Help is required
After implementing suggested Projection Issue still not resolved and here is screen shot
One way would be to use projections like for example:
@Projection(name = "edit" , types = Employee.class)
public interface EditEmployeeProjection {
String getFirstName();
String getLastName();
Set<Project> getProjects();
}
With this the project list will be embedded in the result for http://localhost:8080/api/employee/1?projection=edit
Projections would be used automatically if you add excerptProjection
to you repository like described here: How to expose a complete tree structure with Spring Data REST and HATEOAS?
See for example here: https://shinesolutions.com/2015/04/15/spring-data-rest-and-projections/
EDITED
In you case a projection would look like:
@Projection(name = "edit" , types = UserCompetency.class)
public interface UserCompetencyProjection {
User getUser();
Competency getCompetency();
}
With http://localhost:8080/userCompetencies?projection=edit you would then see wanted result.
EDITED 2 The code I used:
Competency.class
@Entity
@Table(name = "competency", schema = "public")
@JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "competencyId")
public class Competency implements java.io.Serializable {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "competency_id", unique = true, nullable = false)
private Long competencyId;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "competency")
private List<UserCompetency> userCompetencies = new ArrayList<>();
UserCompetency.class
@Entity
@Table(name = "user_competency", schema = "public")
@JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "id")
public class UserCompetency implements java.io.Serializable {
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "competencyId", column = @Column(name = "competency_id", nullable = false)),
@AttributeOverride(name = "userId", column = @Column(name = "user_id", nullable = false)) })
private UserCompetencyId id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
private User user;
@ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
@JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)
private Competency competency;
UserCompetencyId.class
@Embeddable
public class UserCompetencyId implements java.io.Serializable {
@Column(name = "competency_id", nullable = false)
private Long competencyId;
@Column(name = "user_id", nullable = false)
private Long userId;
UserCompetencyRepository.class
@RepositoryRestResource(excerptProjection = UserCompetencyProjection.class)
public interface UserCompetencyRepository extends JpaRepository<UserCompetency, UserCompetencyId> {
After Implementing This ,In my case its not working to show desired jason [![enter image description here][2]][2]
这篇关于在@ManytoMany 关系和具有额外列的查找表的情况下,无法检索 Spring HATEOAS 嵌入的资源对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!