I have a Spring Data Repository
over a single JPA entity. This entity is subclassed via joined inheritance.
Spring Data REST seems to have a problem interpreting this structure, at least automatically. Or maybe I'm misunderstanding the usage of Inheritance.JOINED
Any request for any entity with an Event
returns the following:
{
cause: null,
message: "Cannot create self link for class com.foo.event.SubEvent! No persistent entity found!"
}
Maybe I'm asking too much for this project to know how to handle this, but is there a workaround that would group all of my Events
under the same /events
? Maybe even allowing me to filter on type?
I've left the basics of the application structure below.
Event.java
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({
@Type(value = SubEvent.class),
...
})
...
public class Event {
@Id
private long id;
...
}
SubEvent.java
@Entity
public class SubEvent extends Event {
private String code;
...
}
EventRepository.java
@RepositoryRestResource(path = "events")
public interface EventRepository extends PagingAndSortingRepository<Event, Long> {
...
}
I think you're missing using Discriminator
to let JPA understand what subclass to use for a given object (how does it know otherwise?).
I tend to use abstract classes for table-per-subclass hireachies, so here's an example adapted to that for you:
Event.java
@Entity
@DiscriminatorColumn(name = "type")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Event {
@Id
@GeneratedValue
public Long id;
public String type;
}
SubEvent.java
@Entity
@DiscriminatorValue("subevent")
@PrimaryKeyJoinColumn(name = "event_id")
public class PeeringService extends Service {
private String code;
}
With the above code, you'll notice something odd however - when generating the resource path for one of these objects, it assumes you have a Repository
for each subclass, and generates something like this:
{
"type" : "subevent",
"code" : "bacon",
"_links" : {
"self" : {
"href" : "http://localhost:8081/subEvents/1"
},
"peeringService" : {
"href" : "http://localhost:8081/subEvents/1"
}
}
}
This is pretty easy to fix though, you just need to add the following annotation to your base class:
@RestResource(path = "events")
And it will generate the resource paths you'd expect!
Hope this helps :)
I tried you classes out in a simple spring boot project nd they didn't give me any problems and I couldn't reproduce the issue you are having. However, search on the error message you describe gives a couple of posts that suggest that you need to create a SubEvent
repository even f you don't use it, and that the problem arises in more complicated projects, such as using REST.
Reference: Cannot create self link for class X. No persistent entity found.
How to choose MappingContext in spring-data-jpa (2x) + spring-rest-webmvc?
So, try adding a SubEvent repository:
interface SubEventRepository extends CrudRepository<SubEvent, Long> {
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With