Open exports opened 7 years ago
I've the same problem, when I declare my entities with @JsonApiResource annotation, it seems katharsis ignore them or does not apply mapping type specified. The github "spring-boot-examples" repository show an example to implement a specific JpaMapper in order to have two classes : one for the entity (with @Entity annotation) and the other with a DTO (with @JsonApiResource). This solution works but I'm looking for another easier solution to have my entities with the @JsonApiResource, because without the jpa module the annotation worked fine.
Did anyone get an idea on it ?
@loickR Is your mapped entity approach works fine? I cannot create new resource when use mapped entity, and the validation module is broken, so I have to patch the whole module to make it work.
I think so but currently, I've three classes my entity User (with @Entity and @JsonApiResource), my repository and my JpaConfig class implementing the SpringTransactionRunner bean and the JpaModule (like the example on github). Here the code of my classes
@JsonApiResource(type = "users")
@Entity
@Table (name = "users")
@EqualsAndHashCode(of = "firstName")
@NoArgsConstructor
public class User {
@Getter
@Setter
@JsonApiId
@Id
@GeneratedValue (strategy = GenerationType.AUTO)
private Long id;
@Getter
@Setter
@Column
@JsonProperty (value = "last-name")
private String lastName;
@Getter
@Setter
@Column
@JsonProperty (value = "first-name")
private String firstName;
}
@Component
public class UserResourceRepository extends JpaEntityRepository<User, Long> {
@Autowired
public UserResourceRepository(JpaModule module) {
super(module, JpaRepositoryConfig.create(User.class));
}
}
@Configuration
public class JpaConfig {
@Autowired
private EntityManager em;
@Autowired
private TransactionRunner transactionRunner;
@Bean
public SpringTransactionRunner transactionRunner() {
return new SpringTransactionRunner();
}
@Bean
public JpaModule jpaModule() {
final JpaModule module = JpaModule.newServerModule(em, transactionRunner);
return module;
}
}
My application.yml
katharsis:
resourcePackage: com.my_package
domainName: http://localhost:8080
pathPrefix: /api
jpa:
enabled: false
spring:
datasource:
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/my_db
username: user
password: user_pass
jpa:
hibernate:
ddl-auto: update
show-sql: true
I'm switching to mapped dto so I can modify the type now.
And btw, there is an undocumented KatharsisJpaAutoConfiguration
in the latest version which will automatically discover and load all your entities as resources if no bean type of JpaModule present, so you can safely remove the jpaConfig and let the autoconfigure thing handle these stuff for you
one could extend the JpaResourceInformationBuilder.getResourceType. Currently it already checks a (deprecated) "JpaResource" annotation. Maybe that one should be de-deprecated.
All of that is a bit historic due to the old resource lookup mechanism which is then has been refactored. Potentially one could also check for JsonApiResource. Which would be better.
Okay, thanks for the reply :). @exports Yes I already checked on it but I need to define manually my repositories in order to customize them for CRUD operations. @remmeier I don't understand how does JpaResourceInformationBuilder work and how can I use it ? My repositories must extends it or these my entities ? Anyway, I've seen the annotation what you meant "@JpaResource" it would be fine if a future support for that may be released (as you mention it, it's deprecated right now). For the moment, I check on split my entities and my dto classes and waiting for a stronger support between spring and katharsis.
JpaResourceInformationBuilder is the thing taking care of parsing all the annotations. So more support in this area has to be implemented there. For know you can just use @JpaResource and we can either de-deprecate it or introduce a better solution.
Okay I got it, I've seen some tests using it and I'm going to see further. I don't really know if in a next feature you guys can make directly a such update with @JpaResource but thanks by the way for your explanation, katharsis is a good framework :) Maybe it can solve my problems with annotation because my url http://localhost:8080/users doesn't work and http://localhost:8080/user works at well.
Hi @remmeier , everyone,
I'm facing the same issue, trying to expose an entity to its pluralized form (or any other string provided by an annotation on this entity).
As mentionned on the Gitter (may 02), @JsonApiResource
is ignored when direct-exposing an entity, this left us with the deprecated (and buggy?) @JpaResource
.
Without @JpaResource
:
@Entity
public class Person {
}
is exposed at http://host:port/api-prefix/person
.
But application crash at startup when adding @JpaResource
to the entity:
Caused by: java.lang.UnsupportedOperationException: unknown type class com.sncf.igtl.re.katharsis.Person
at io.katharsis.meta.MetaLookup.allocateMeta(MetaLookup.java:206) ~[katharsis-meta-3.0.1.jar:na]
After a little diggin', I suppose that when JpaResourceInformationBuilder
try to build()
resource information for a class and detect the annotation, it tries to retrieve meta using the JpaMetaLookup
, which lacks a MetaJsonObject
object provider (ResourceMetaProvider
has one).
Questions now!
Am I doing right? Is this a bug or misconfiguration? How can I provide custom resource type when exposing a JPA entity? DTO is one solution but left us with a lot of boilerplate code.
So far changing the name has not really be attempted so I would consider it not being supported. But that can be changed (altough personally I prefer sticking to the naming of the entities, because it involves just more work without significant benefit).
I would need to the see entire exception. But we should wait a few days. There is a fairly substantial backlog when it comes to accepting PRs. On top of the PRs I have quite a large number of further improvements to katharsis-meta that I was not able to contribute. But @hibaymj is currently looking into the PRs.
Thanks for this answer.
But that can be changed (altough personally I prefer sticking to the naming of the entities, because it involves just more work without significant benefit).
I beg to differ. Java naming convention for entity class name is singular, and REST API often (despite the lack of specification or consensus for this specific topic) expose resources with plural form. JSON API examples use plural form URI, frameworks like Ember also expect /api/users
instead of /api/user
.
There is a fairly substantial backlog when it comes to accepting PRs. On top of the PRs I have quite a large number of further improvements to katharsis-meta that I was not able to contribute. But @hibaymj is currently looking into the PRs.
No rush here, I understand there is quite some work to do. Can you - or other maintainers - just tell us if this is planned to be supported?
I would need to the see entire exception.
There you are:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.3.RELEASE)
2017-05-05 10:39:48.816 INFO 3116 --- [ main] com.foo.katharsis.Application : Starting Application on host with PID 3116 (D:\workspace\test-katharsis-spring\target\classes started by user in D:\workspace\test-katharsis-spring)
2017-05-05 10:39:48.820 INFO 3116 --- [ main] com.foo.katharsis.Application : No active profile set, falling back to default profiles: default
2017-05-05 10:39:48.950 INFO 3116 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@279ad2e3: startup date [Fri May 05 10:39:48 CEST 2017]; root of context hierarchy
2017-05-05 10:39:52.449 INFO 3116 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2017-05-05 10:39:52.469 INFO 3116 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2017-05-05 10:39:52.471 INFO 3116 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.14
2017-05-05 10:39:52.684 INFO 3116 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-05-05 10:39:52.684 INFO 3116 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3739 ms
2017-05-05 10:39:53.701 INFO 3116 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2017-05-05 10:39:53.729 INFO 3116 --- [ost-startStop-1] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2017-05-05 10:39:53.867 INFO 3116 --- [ost-startStop-1] org.hibernate.Version : HHH000412: Hibernate Core {5.0.12.Final}
2017-05-05 10:39:53.869 INFO 3116 --- [ost-startStop-1] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2017-05-05 10:39:53.871 INFO 3116 --- [ost-startStop-1] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2017-05-05 10:39:53.951 INFO 3116 --- [ost-startStop-1] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2017-05-05 10:39:54.292 INFO 3116 --- [ost-startStop-1] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2017-05-05 10:39:54.970 INFO 3116 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2017-05-05 10:39:54.990 INFO 3116 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2017-05-05 10:39:55.063 INFO 3116 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2017-05-05 10:39:55.172 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding
2017-05-05 10:39:55.172 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added
2017-05-05 10:39:55.173 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : allocate class com.foo.katharsis.Person
2017-05-05 10:39:55.229 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : add com.foo.katharsis.Person of type MetaEntity
2017-05-05 10:39:55.230 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : add com.foo.katharsis.Person.name of type MetaEntityAttribute
2017-05-05 10:39:55.230 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : add com.foo.katharsis.Person.id of type MetaEntityAttribute
2017-05-05 10:39:55.230 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : add com.foo.katharsis.Person.Person$primaryKey of type MetaPrimaryKey
2017-05-05 10:39:55.230 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding
2017-05-05 10:39:55.230 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding com.foo.katharsis.Person
2017-05-05 10:39:55.230 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding com.foo.katharsis.Person.name
2017-05-05 10:39:55.232 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : allocate class java.lang.String
2017-05-05 10:39:55.233 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : add base.string of type MetaPrimitiveType
2017-05-05 10:39:55.233 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added com.foo.katharsis.Person.name
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding com.foo.katharsis.Person.id
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : allocate class java.lang.Long
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : add base.long of type MetaPrimitiveType
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added com.foo.katharsis.Person.id
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding com.foo.katharsis.Person.Person$primaryKey
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added com.foo.katharsis.Person.Person$primaryKey
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added com.foo.katharsis.Person
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding base.string
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added base.string
2017-05-05 10:39:55.234 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding base.long
2017-05-05 10:39:55.235 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added base.long
2017-05-05 10:39:55.235 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added
2017-05-05 10:39:55.252 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding
2017-05-05 10:39:55.252 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added
2017-05-05 10:39:55.252 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : adding
2017-05-05 10:39:55.252 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : added
2017-05-05 10:39:55.277 DEBUG 3116 --- [ost-startStop-1] io.katharsis.meta.MetaLookup : allocate class com.foo.katharsis.Person
2017-05-05 10:39:55.278 ERROR 3116 --- [ost-startStop-1] o.s.b.c.embedded.tomcat.TomcatStarter : Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'springBootSampleKatharsisFilter' defined in io.katharsis.spring.boot.v3.KatharsisConfigV3: Unsatisfied dependency expressed through method 'springBootSampleKatharsisFilter' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'katharsisBoot' defined in io.katharsis.spring.boot.v3.KatharsisConfigV3: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.katharsis.core.internal.boot.KatharsisBoot]: Factory method 'katharsisBoot' threw exception; nested exception is java.lang.UnsupportedOperationException: unknown type class com.foo.katharsis.Person
2017-05-05 10:39:55.314 WARN 3116 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
2017-05-05 10:39:55.315 INFO 3116 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2017-05-05 10:39:55.315 INFO 3116 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2017-05-05 10:39:55.323 INFO 3116 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2017-05-05 10:39:55.340 ERROR 3116 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:536) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at com.foo.katharsis.Application.main(Application.java:13) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:na]
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:123) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:84) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:554) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:179) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
... 13 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'springBootSampleKatharsisFilter' defined in io.katharsis.spring.boot.v3.KatharsisConfigV3: Unsatisfied dependency expressed through method 'springBootSampleKatharsisFilter' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'katharsisBoot' defined in io.katharsis.spring.boot.v3.KatharsisConfigV3: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.katharsis.core.internal.boot.KatharsisBoot]: Factory method 'katharsisBoot' threw exception; nested exception is java.lang.UnsupportedOperationException: unknown type class com.foo.katharsis.Person
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:234) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:182) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:177) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:159) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:80) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:241) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:228) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:89) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:213) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:55) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_91]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_91]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'katharsisBoot' defined in io.katharsis.spring.boot.v3.KatharsisConfigV3: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.katharsis.core.internal.boot.KatharsisBoot]: Factory method 'katharsisBoot' threw exception; nested exception is java.lang.UnsupportedOperationException: unknown type class com.foo.katharsis.Person
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
... 27 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.katharsis.core.internal.boot.KatharsisBoot]: Factory method 'katharsisBoot' threw exception; nested exception is java.lang.UnsupportedOperationException: unknown type class com.foo.katharsis.Person
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
... 40 common frames omitted
Caused by: java.lang.UnsupportedOperationException: unknown type class com.foo.katharsis.Person
at io.katharsis.meta.MetaLookup.allocateMeta(MetaLookup.java:206) ~[katharsis-meta-3.0.1.jar:na]
at io.katharsis.meta.MetaLookup.getMetaInternal(MetaLookup.java:146) ~[katharsis-meta-3.0.1.jar:na]
at io.katharsis.meta.MetaLookup.getMeta(MetaLookup.java:119) ~[katharsis-meta-3.0.1.jar:na]
at io.katharsis.jpa.internal.JpaResourceInformationBuilder.build(JpaResourceInformationBuilder.java:97) ~[katharsis-jpa-3.0.1.jar:na]
at io.katharsis.module.ModuleRegistry$CombinedResourceInformationBuilder.build(ModuleRegistry.java:310) ~[katharsis-core-3.0.1.jar:na]
at io.katharsis.core.internal.repository.information.DefaultResourceRepositoryInformationBuilder.build(DefaultResourceRepositoryInformationBuilder.java:55) ~[katharsis-core-3.0.1.jar:na]
at io.katharsis.core.internal.repository.information.DefaultResourceRepositoryInformationBuilder.build(DefaultResourceRepositoryInformationBuilder.java:44) ~[katharsis-core-3.0.1.jar:na]
at io.katharsis.module.ModuleRegistry$CombinedRepositoryInformationBuilder.build(ModuleRegistry.java:360) ~[katharsis-core-3.0.1.jar:na]
at io.katharsis.module.ModuleRegistry.applyRepositoryRegistration(ModuleRegistry.java:463) ~[katharsis-core-3.0.1.jar:na]
at io.katharsis.module.ModuleRegistry.init(ModuleRegistry.java:426) ~[katharsis-core-3.0.1.jar:na]
at io.katharsis.core.internal.boot.KatharsisBoot.bootDiscovery(KatharsisBoot.java:194) ~[katharsis-core-3.0.1.jar:na]
at io.katharsis.core.internal.boot.KatharsisBoot.boot(KatharsisBoot.java:176) ~[katharsis-core-3.0.1.jar:na]
at io.katharsis.spring.boot.v3.KatharsisConfigV3.katharsisBoot(KatharsisConfigV3.java:52) ~[katharsis-spring-3.0.1.jar:na]
at io.katharsis.spring.boot.v3.KatharsisConfigV3$$EnhancerBySpringCGLIB$$a05f1399.CGLIB$katharsisBoot$4(<generated>) ~[katharsis-spring-3.0.1.jar:na]
at io.katharsis.spring.boot.v3.KatharsisConfigV3$$EnhancerBySpringCGLIB$$a05f1399$$FastClassBySpringCGLIB$$2050ba9c.invoke(<generated>) ~[katharsis-spring-3.0.1.jar:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at io.katharsis.spring.boot.v3.KatharsisConfigV3$$EnhancerBySpringCGLIB$$a05f1399.katharsisBoot(<generated>) ~[katharsis-spring-3.0.1.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
... 41 common frames omitted
Process finished with exit code 1
Codebase used for this test case:
application.properties
katharsis.jpa.enabled=true
Application.java
@SpringBootApplication
@Import({KatharsisConfigV3.class})
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
Person.java
// Uncomment to unleash 'unknown type class com.foo.katharsis.Person'
// @JpaResource(type = "people")
@Entity @Getter @Setter
@NoArgsConstructor(access = AccessLevel.PACKAGE)
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
yes, plural is nicer. JSON API says:
Note: This spec is agnostic about inflection rules, so the value of type can be either plural or singular. However, the same value should be used consistently throughout an implementation.
I consider myself just being too lazy for this kind of things and take the shortest route...
The maintance topics is currently being discussed. I'm not a maintainer and the past working mode was not really a working working mode.
Thx for the exception. I fixed it locally in my repository. It will find its way into the official one with all the other changes.
This issue of plural and inflection came up several times. The pluralization needs to be at the controller
level to make sense: If you think of this in HTTP terms, orginally, HTTP was basically a webified file system . So, if I had some documents I would naturally put them in a directory called /documents
but each is a singular document
so, if I did an ls /documents
I would get:
doc1.doc
doc2.doc
So, Ideally you would POST a single document
to documents
. IN JSONApi, you declare the type when you post and in this case you would declare
{
attributes: {
type: 'document'
}
}
However, the way katharsis is implemented, it is not possible to make the distinction between plural and singular in the correct cases. So, if you declare your JSONApi entity as document
then when you post the payload looks good but you end up posting to a resource called document
(no plural). If you make the resource plural to fix this then the payload type is plural.
There has been discussion of using an inflection library to bypass this and get smart about it (The one spring-data-rest uses is pretty good for english) but naturally the angry mob comes and says, in summary: "YOU HAVE TO SUPPORT MY LANGUAGE TOO! Vive la resistance!" - never mind the fact the the entire web is still english/ascii oriented.
At this point, I would support the use of an inflector and with entity declaration being singular and just limit it to English.
If you're interested, I can point you at the inflector in use and we can work on a PR
@remmeier could you tell me if recent version (3.0.3 ?) enable the @JpaResource(type = "people")
usage?
Is there any consensus about plural form for JPA entity through direct mapping? Will @JpaResource
stay deprecated?
Thanks!
I try to set the resource type for a jpa entity with
@JsonApiResource
in katharsis-jpa, but it does not work.