在@ManytoMany 关系和具有额外列的查找表的情况下,无法检索 Spring HATEOAS 嵌入的资源对象 [英] Unable to retrieve Spring HATEOAS embedded resource object in case of @ManytoMany relationship and lookup table with extra column

查看:18
本文介绍了在@ManytoMany 关系和具有额外列的查找表的情况下,无法检索 Spring HATEOAS 嵌入的资源对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法检索嵌入式.我正在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆