Spring Data Rest encounters a composite primary key

If the project persistence layer uses Spring Data JPA and some data tables contain composite primary keys (Union primary keys), how can the interface generated by Spring Data Rest access the data corresponding to a primary key in these data tables?

Suppose the database has two data tables film with compound primary key_ Actor and film_category, corresponding to the following four classes.

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.sql.Timestamp;

@Entity
@Table(name = "film_actor")
public class FilmActor implements Serializable {

    @EmbeddedId
    @AttributeOverrides({
            @AttributeOverride(name = "actorId", column = @Column(name = "actor_id", nullable = false)),
            @AttributeOverride(name = "filmId", column = @Column(name = "film_id", nullable = false))})
    private FilmActorId id;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "last_update", nullable = false, length = 19)
    private Date lastUpdate;

    //constructor,getter/setter
}

@Embeddable
public class FilmActorId implements java.io.Serializable {

    @Column(name = "actor_id", nullable = false)
    private short actorId;

    @Column(name = "film_id", nullable = false)
    private short filmId;

    //constructor,getter/setter,equals,hashCode
 }

@Entity
@Table(name = "film_category")
@IdClass(FilmCategoryPK.class)
public class FilmCategory {

    @Id
    @Column(name = "film_id", nullable = false)
    private short filmId;

    @Id
    @Column(name = "category_id", nullable = false)
    private byte categoryId;

    @Basic
    @Column(name = "last_update", nullable = false)
    private Timestamp lastUpdate;

    //constructor,getter/setter,equals,hashCode
}

public class FilmCategoryPK implements Serializable {

    @Column(name = "film_id", nullable = false)
    @Id
    private short filmId;

    @Column(name = "category_id", nullable = false)
    @Id
    private byte categoryId;

    //constructor,getter/setter,equals,hashCode
}

The above code represents two ways of ORM.
How to get the film through the interface generated by Spring Data Rest_ What about the records with ID 1 in the actor table?

That involves converting the request URL to an entity class ID. The following configuration needs to be added

import org.springframework.data.rest.webmvc.spi.BackendIdConverter;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.Arrays;

@Component
public class IdConverter implements BackendIdConverter {

    private ThreadLocal<String> threadLocal = new ThreadLocal<>();

    @Override
    public Serializable fromRequestId(String s, Class<?> clazz) {
        System.out.println(String.format("fromRequestId(%s,%s)", s, clazz));
        threadLocal.set(s);

        String[] ss = s.split(",");
        long p1 = Long.parseLong(ss[0]);
        long p2 = Long.parseLong(ss[1]);

        if (clazz == FilmActor.class)
            return new FilmActorId(((short) p1), ((short) p2));

        if (clazz == FilmCategory.class)
            return new FilmCategoryPK(((short) p1), ((byte) p2));

        return null;
    }

    @Override
    public String toRequestId(Serializable serializable, Class<?> clazz) {
        System.out.println(String.format("toRequestId(%s,%s)", serializable, clazz));
        System.out.println(serializable.getClass());
        return threadLocal.get();
    }

    @Override
    public boolean supports(Class<?> clazz) {
        System.out.println(String.format("supports(%s)", clazz));
        return Arrays.asList(FilmActor.class, FilmCategory.class).contains(clazz);
    }
}

Now visit http://localhost:8080/FilmActor/1,1 You can get the film_actor table
Middle actor_id and film_id's all 1 records.

Attached:
Comments on Spring Data Rest:
Although the database can be transformed into a common RESTful API with very little code, there are many problems, such as security and performance problems. To solve these problems, more code is needed, which may not pay off. At the same time, these APIs are difficult to deal with complex business scenarios. Therefore, Spring Data Rest is not suitable for practical projects, especially Internet projects.

Tags: Java Spring REST Database

Posted on Sun, 31 May 2020 02:44:39 -0700 by volleytotal.ch