在@ManytoMany 关系和查找 table 的情况下,无法检索 Spring HATEOAS 嵌入式资源对象

Unable to retrieve Spring HATEOAS embedded resource object in case of @ManytoMany relationship and lookup table with extra column

我无法检索嵌入式。我正在使用 Spring 引导,spring 数据休息和 spring JPA。我在数据库中有 3 tables

用户

@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;
        }
    }   

用户能力

    @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());
    }    
}

用户能力资料库

  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>

并且我想使用 URI 执行 GET,它 return 我嵌入了对象并且无法获取对象属性的实际值
获取 http://localhost:8080/userCompetencies


如何获取用户和能力对象的属性值,其中 userId=8 需要帮助

实施建议的投影问题后仍未解决,这是屏幕截图

一种方法是使用投影,例如:

@Projection(name = "edit" , types = Employee.class)
public interface EditEmployeeProjection {
    String getFirstName();
    String getLastName();
    Set<Project> getProjects();
}

这样,项目列表将嵌入到 http://localhost:8080/api/employee/1?projection=edit

的结果中

如果您将 excerptProjection 添加到您的存储库,将自动使用投影,如下所述:How to expose a complete tree structure with Spring Data REST and HATEOAS?

参见此处的示例:https://shinesolutions.com/2015/04/15/spring-data-rest-and-projections/

已编辑

在你的情况下,投影看起来像:

@Projection(name = "edit" , types = UserCompetency.class)
public interface UserCompetencyProjection {
    User getUser();
    Competency getCompetency();
}

使用 http://localhost:8080/userCompetencies?projection=edit 你会看到想要的结果。

已编辑 2 我使用的代码:

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<>();

用户Competency.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]

成功了,实际上我在 UserCompetencyRepository class 上缺少
@RepositoryRestResource(excerptProjection = UserCompetencyProjection.class) 的注释 class 现在输出看起来像这样我正在跳过输出,并放置必要的输出.