-
Notifications
You must be signed in to change notification settings - Fork 563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inheritance of entities/repositories [DATAREST-344] #726
Comments
Oliver Drotbohm commented I think falling back to a repo per concrete type is not a good idea. You shouldn't need to tweak your repository setup that much to get the output you want. Have you tried registering a |
Benjamin M commented There's one situation when fallback would be pretty awesome: Basically I did only want to use a single repository for all 3 entities:
Jackson handles this pretty well, because I have:
(Maybe this would be a nice default for So I can do:
POSTing data this way, inserts it into the database, but the HTTP response fails for the same reason as the GET request:
— Now I'll try to find out, how this — EDIT: Now figured out how to write my own
But I don't know how/where to register it. Inside Search goes on... — Here ( https://github.com/spring-projects/spring-hateoas ) it's said "automatically picks up all RelProvider implementations in the ApplicationContext and bundles them into a DelegatingRelProvider available for autowiring."
I did the following:
But when I call |
Pablo Santiago commented Just adding my 2 cents here: arg0.isAssignableFrom(Message.class) Was returning org.apache.commons.lang3.ClassUtils.isAssignable(arg0, Message.class); And now I get the correct information |
Manuel Sousa commented I used the above suggestion and it fixed the _embedded so that it would show all subclasses. However in the _links it still uses the subclassname instead of the value returned by getItemResourceRelFor. Did this also happen for you / did you manage to fix it? In my case this is breaking access from the hateoas links so I needed to create one repository for each subclass again, still better than nothing being able to access by the superclass |
David Riccitelli commented I was able to solve setting the path on the subclass repositories, e.g: @RepositoryRestResource(exported = false, path = "messages")
public interface TextMessageRepo extends JpaRepository<TextMessage, UUID> { }
(...) |
Firoz Fazil commented A dirty fix. In the above example make the subclass repository private so that the names can be changed to the parents and the endpoints will still be exposed by the repository of the parent. @RepositoryRestResource(exported = false, path = "messages")
interface TextMessageRepo extends JpaRepository<TextMessage, UUID> {
} |
Mathias Ewald commented I just tried that (using the RelProvider above and non-exported Repo suggested just before my comment here) and I am seeing some strange behavior.
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.4.RELEASE)
2019-04-28 12:45:04.733 INFO 42556 --- [ main] c.e.s.SdrInheritanceApplication : Starting SdrInheritanceApplication on mewald.local with PID 42556 (/Users/mewald/Downloads/sdr-inheritance/target/classes started by mewald in /Users/mewald/Downloads/sdr-inheritance)2019-04-28 12:45:04.735 INFO 42556 --- [ main] c.e.s.SdrInheritanceApplication : No active profile set, falling back to default profiles: default2019-04-28 12:45:05.264 INFO 42556 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.2019-04-28 12:45:05.308 INFO 42556 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 39ms. Found 3 repository interfaces.2019-04-28 12:45:05.553 INFO 42556 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$3dae109f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)2019-04-28 12:45:05.567 INFO 42556 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.hateoas.config.HateoasConfiguration' of type [org.springframework.hateoas.config.HateoasConfiguration$$EnhancerBySpringCGLIB$$bd2e5dd1] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)2019-04-28 12:45:05.829 INFO 42556 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)2019-04-28 12:45:05.846 INFO 42556 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]2019-04-28 12:45:05.846 INFO 42556 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.17]2019-04-28 12:45:05.905 INFO 42556 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext2019-04-28 12:45:05.906 INFO 42556 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1139 ms2019-04-28 12:45:06.061 INFO 42556 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...2019-04-28 12:45:06.124 INFO 42556 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.2019-04-28 12:45:06.166 INFO 42556 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [ name: default ...]2019-04-28 12:45:06.290 INFO 42556 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.3.9.Final}2019-04-28 12:45:06.290 INFO 42556 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found2019-04-28 12:45:06.360 INFO 42556 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}2019-04-28 12:45:06.432 INFO 42556 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect2019-04-28 12:45:06.496 WARN 42556 --- [ main] org.hibernate.cfg.AnnotationBinder : HHH000457: Joined inheritance hierarchy [com.example.sdrinheritance.Feedback] defined explicit @DiscriminatorColumn. Legacy Hibernate behavior was to ignore the @DiscriminatorColumn. However, as part of issue HHH-6911 we now apply the explicit @DiscriminatorColumn. If you would prefer the legacy behavior, enable the `hibernate.discriminator.ignore_explicit_for_joined` setting (hibernate.discriminator.ignore_explicit_for_joined=true)2019-04-28 12:45:06.810 INFO 42556 --- [ main] o.h.t.schema.internal.SchemaCreatorImpl : HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@11ede87f'2019-04-28 12:45:06.812 INFO 42556 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'2019-04-28 12:45:07.492 INFO 42556 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'2019-04-28 12:45:07.521 WARN 42556 --- [ main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning2019-04-28 12:45:07.784 INFO 42556 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''2019-04-28 12:45:07.787 INFO 42556 --- [ main] c.e.s.SdrInheritanceApplication : Started SdrInheritanceApplication in 3.296 seconds (JVM running for 3.835)2019-04-28 12:45:07.816 INFO 42556 --- [ main] com.example.sdrinheritance.DataLoader : Feedbacks saved
$ curl http://localhost:8080
{
"_links" : {
"feedbacks" : {
"href" : "http://localhost:8080/feedbacks"
},
"profile" : {
"href" : "http://localhost:8080/profile"
}
}
}
curl -v http://localhost:8080/feedbacks
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /feedbacks HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 404
< Content-Type: application/hal+json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 28 Apr 2019 10:47:17 GMT
<
* Connection #0 to host localhost left intact
{"timestamp":"2019-04-28T10:47:17.196+0000","status":404,"error":"Not Found","message":"No message available","path":"/feedbacks"}
These are the logs I can see switching to DEBUG mode:
[2m2019-04-28 12:49:16.599[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[l-1 housekeeper][0;39m [36mcom.zaxxer.hikari.pool.HikariPool [0;39m [2m:[0;39m HikariPool-1 - Pool stats (total=10, active=0, idle=10, waiting=0)
[2m2019-04-28 12:49:16.607[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[8080-Acceptor-0][0;39m [36mo.apache.tomcat.util.threads.LimitLatch [0;39m [2m:[0;39m Counting up[http-nio-8080-Acceptor-0] latch=1
[2m2019-04-28 12:49:16.608[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.tomcat.util.net.SocketWrapperBase [0;39m [2m:[0;39m Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@3de12d42:org.apache.tomcat.util.net.NioChannel@1ad6e3b1:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:52893]], Read from buffer: [0]
[2m2019-04-28 12:49:16.608[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36morg.apache.tomcat.util.net.NioEndpoint [0;39m [2m:[0;39m Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@3de12d42:org.apache.tomcat.util.net.NioChannel@1ad6e3b1:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:52893]], Read direct from socket: [87]
[2m2019-04-28 12:49:16.608[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.coyote.http11.Http11InputBuffer [0;39m [2m:[0;39m Received [GET /feedbacks HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.54.0
Accept: */*
]
[2m2019-04-28 12:49:16.609[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.c.authenticator.AuthenticatorBase [0;39m [2m:[0;39m Security checking request GET /feedbacks
[2m2019-04-28 12:49:16.609[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36morg.apache.catalina.realm.RealmBase [0;39m [2m:[0;39m No applicable constraints defined
[2m2019-04-28 12:49:16.609[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.c.authenticator.AuthenticatorBase [0;39m [2m:[0;39m Not subject to any constraint
[2m2019-04-28 12:49:16.609[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36morg.apache.tomcat.util.http.Parameters [0;39m [2m:[0;39m Set encoding to UTF-8
[2m2019-04-28 12:49:16.610[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m GET "/feedbacks", parameters={}
[2m2019-04-28 12:49:16.614[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.w.s.handler.SimpleUrlHandlerMapping [0;39m [2m:[0;39m Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
[2m2019-04-28 12:49:16.614[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.j.s.OpenEntityManagerInViewInterceptor[0;39m [2m:[0;39m Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
[2m2019-04-28 12:49:16.616[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.w.s.r.ResourceHttpRequestHandler [0;39m [2m:[0;39m Resource not found
[2m2019-04-28 12:49:16.616[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.j.s.OpenEntityManagerInViewInterceptor[0;39m [2m:[0;39m Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
[2m2019-04-28 12:49:16.616[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m Completed 404 NOT_FOUND
[2m2019-04-28 12:49:16.616[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.c.c.C.[Tomcat].[localhost] [0;39m [2m:[0;39m Processing ErrorPage[errorCode=0, location=/error]
[2m2019-04-28 12:49:16.619[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m "ERROR" dispatch for GET "/error", parameters={}
[2m2019-04-28 12:49:16.620[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36ms.w.s.m.m.a.RequestMappingHandlerMapping[0;39m [2m:[0;39m Mapped to public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
[2m2019-04-28 12:49:16.620[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.j.s.OpenEntityManagerInViewInterceptor[0;39m [2m:[0;39m Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
[2m2019-04-28 12:49:16.625[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.w.s.m.m.a.HttpEntityMethodProcessor [0;39m [2m:[0;39m Using 'application/hal+json', given [*/*] and supported [application/hal+json]
[2m2019-04-28 12:49:16.627[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.w.s.m.m.a.HttpEntityMethodProcessor [0;39m [2m:[0;39m Writing [{timestamp=Sun Apr 28 12:49:16 CEST 2019, status=404, error=Not Found, message=No message available, (truncated)...]
[2m2019-04-28 12:49:16.641[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.j.s.OpenEntityManagerInViewInterceptor[0;39m [2m:[0;39m Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
[2m2019-04-28 12:49:16.641[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m Exiting from "ERROR" dispatch, status 404
[2m2019-04-28 12:49:16.643[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.c.c.C.[.[.[/].[dispatcherServlet] [0;39m [2m:[0;39m Disabling the response for further output
[2m2019-04-28 12:49:16.644[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.tomcat.util.net.SocketWrapperBase [0;39m [2m:[0;39m Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@3de12d42:org.apache.tomcat.util.net.NioChannel@1ad6e3b1:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:52893]], Read from buffer: [0]
[2m2019-04-28 12:49:16.646[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.apache.coyote.http11.Http11Processor [0;39m [2m:[0;39m Error parsing HTTP request header
java.io.EOFException: null
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1206) ~[tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1140) ~[tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:731) ~[tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:352) ~[tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:294) ~[tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) [tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.17.jar:9.0.17]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.17.jar:9.0.17]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
[2m2019-04-28 12:49:16.646[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.apache.coyote.http11.Http11Processor [0;39m [2m:[0;39m Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@3de12d42:org.apache.tomcat.util.net.NioChannel@1ad6e3b1:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:52893]], Status in: [OPEN_READ], State out: [CLOSED]
[2m2019-04-28 12:49:16.648[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.apache.tomcat.util.threads.LimitLatch [0;39m [2m:[0;39m Counting down[http-nio-8080-exec-2] latch=1
[2m2019-04-28 12:49:16.648[0;39m [32mDEBUG[0;39m [35m42736[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36morg.apache.tomcat.util.net.NioEndpoint [0;39m [2m:[0;39m Socket: [org.apache.tomcat.util.net.NioChannel@1ad6e3b1:java.nio.channels.SocketChannel[closed]] closed
I made this demo code public here for easier reference: https://github.com/mathias-ewald/sdr-inheritance Did this work for anyone?
|
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed. |
It seems like |
Adding a new, However, digging into this a bit more, the logic to calculate the name in the links array is here, and this provides a hint: Lines 73 to 77 in 5c76446
We can also chose our path segment by annotating the JPA Entity with @Entity
@DiscriminatorValue("TEXT")
@JsonTypeName("TEXT")
+@RestResource(rel = "message", path = "messages")
public class TextMessage extends Message { ... }
@Entity
@DiscriminatorValue("TODO")
@JsonTypeName("TODO")
+@RestResource(rel = "message", path = "messages")
public class TodoMessage extends Message { ... } |
Benjamin M opened DATAREST-344 and commented
I'd like to use inheritance for my entities. And the only way of getting it kinda working was to do the following:
When I now call
GET http://localhost:8080/webapp/messages
I get the following output:As you can see, there's
textMessages
andtodoMessages
within the_embedded
object. So, I cannot really sort my messages.Is there a way to get all my messages within a single array?
—
EDIT: I tried to get rid of my additional projections, but that won't work:
If I only have a
@Projection
forMessage.class
, it won't get applied when callingGET http://localhost:8080/webapp/messages?projection=summary
,BUT it does work, if it's an inherited projection:
GET http://localhost:8080/webapp/messageInboxes/89cb89db-67c5-49b3-8f1f-00b63b74ca4a?projection=summary
with:
—
EDIT 2:
I now somehow fixed it / encountered a new bug...
If I put
on all 3 repositories it behaves like I want it to: Every kind of message is available under
GET http://localhost:8080/webapp/messages
and all get displayed within the same array!But now there are 2 issues:
itemResourceRel="message"
to the@RepositoryRestResource
annotation on all 3 repositories, the URLGET http://localhost:8080/webapp/messages
will display randomly either theTextMessages
OR theTodoMessages
, but never bothAffects: 2.1.1 (Dijkstra SR1)
9 votes, 16 watchers
The text was updated successfully, but these errors were encountered: