Spring MVC Repository and Hibernate - spring

Following Spring docs, I've created a maven project with the following dependencies :
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</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.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I'd like to know if Repository data abstraction "goes through" hibernate or not.

From the reference documentation:
28.3 JPA and ‘Spring Data’
The Java Persistence API is a standard technology that allows you to ‘map’ objects to relational databases. The spring-boot-starter-data-jpa POM provides a quick way to get started. It provides the following key dependencies:
Hibernate — One of the most popular JPA implementations.
Spring Data JPA — Makes it easy to easily implement JPA-based repositories.
Spring ORMs — Core ORM support from the Spring Framework.
So the answer is "Yes".
BTW, Spring will create and bootstrap automatically an EntityManagerFactory and DataSource beans by declaring a spring-boot-starter-data-jpa dependency.

If you are unsure which dependencies your project have, you can use the maven-dependency-plugin. Specifically, you can use dependency:tree to get a hierarchal tree view of all dependencies and their transitive dependencies (or dependency:list to get a plain list), e.g.
$ mvn dependency:tree
And to answer your question: Yes, spring-boot-starter-data-jpa does depend on Hibernate:
[INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:1.2.0.RELEASE:compile
[INFO] | +-
[INFO] | +- org.hibernate:hibernate-entitymanager:jar:4.3.7.Final:compile
[INFO] | | +-
[INFO] | | +- org.hibernate:hibernate-core:jar:4.3.7.Final:compile
[INFO] | | | +-
[INFO] | | +-
[INFO] | | +- org.hibernate.common:hibernate-commons-annotations:jar:4.0.5.Final:compile
[INFO] | | +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO] | | +-

Related

Why do we need to add additional dependency for log42j in Spring Boot?

Why do we need to add an additional dependency for log42j since all the transitive dependencies are already present in spring-boot-starter-web?
From whatever tutorials I could read up on the internet everybody mentioned to add the dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
They also mentioned excluding spring-boot-starter-logging from spring-boot-starter-web.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
But why do we need to do this? I see all the dependencies in spring-boot-starter-log4j2 are already there in spring-boot-starter-logging.
The default dependency for logging is not log4j but logback. If you remove the dependency, ideally speaking you should not be able to use the log4j imports in your project. Can you check this once?
The log4j dependency is only declared in the dependency-management, but you would need to include the dependency to be able to use this declared dependency.
Reference: https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/howto-logging.html
Spring by default logging is backed by Logback which is powered by Apache. So if you want to provide logging in the system you can do so using logback. Now if you are asking the question for exclusion for logback it is just for letting spring know that you are using the different logging framework.
Logging
When spring-boot-starter-logging is included:
org.springframework.boot:spring-boot-starter-logging:jar:2.4.2:compile
+- ch.qos.logback:logback-classic:jar:1.2.3:compile
| +- ch.qos.logback:logback-core:jar:1.2.3:compile
| \- org.slf4j:slf4j-api:jar:1.7.30:compile
+- org.apache.logging.log4j:log4j-to-slf4j:jar:2.13.3:compile
| \- org.apache.logging.log4j:log4j-api:jar:2.13.3:compile
\- org.slf4j:jul-to-slf4j:jar:1.7.30:compile
, then log4j-core does not exist.
On the other hand, when spring-boot-starter-log4j2 is included:
org.springframework.boot:spring-boot-starter-log4j2:jar:2.4.2:compile
+- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.13.3:compile
| +- org.slf4j:slf4j-api:jar:1.7.30:compile
| \- org.apache.logging.log4j:log4j-api:jar:2.13.3:compile
+- org.apache.logging.log4j:log4j-core:jar:2.13.3:compile
+- org.apache.logging.log4j:log4j-jul:jar:2.13.3:compile
\- org.slf4j:jul-to-slf4j:jar:1.7.30:compile
, then it exists.

Understanding Maven Dependency tree output

I am trying to compile a Spring application in which the ApplicationConfig file has #EnableAspectJAutoProxy anotation I am facing this error when trying to run the project:
Failed to instantiate [org.springframework.aop.aspectj.annotation.
AnnotationAwareAspectJAutoProxyCreator]:
Constructor threw exception; nested exception is
java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
I have to say when I remove the above annotation the project is running successfully.
Having read on Internet I thought maybe it's because of incompatible versions for of libraries and jar files.
When I run mvn dependency:tree the output is as below:
[INFO] task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
[INFO] groupId:myProject:jar:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.11:compile
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:compile
[INFO] +- org.springframework:spring-webmvc:jar:4.3.0.RELEASE:compile
[INFO] | +- org.springframework:spring-aop:jar:4.2.6.RELEASE:compile (version m
anaged from 4.3.0.RELEASE)
[INFO] | | \- aopalliance:aopalliance:jar:1.0:compile
[INFO] | +- org.springframework:spring-beans:jar:4.2.6.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:4.2.6.RELEASE:compile (versi
on managed from 4.3.0.RELEASE)
[INFO] | +- org.springframework:spring-core:jar:4.2.6.RELEASE:compile
[INFO] | +- org.springframework:spring-expression:jar:4.2.6.RELEASE:compile
[INFO] | \- org.springframework:spring-web:jar:4.2.6.RELEASE:compile (version m
anaged from 4.3.0.RELEASE)
[INFO] +- org.aspectj:aspectjweaver:jar:1.8.9:compile
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:compile
[INFO] \- org.aspectj:aspectjrt:jar:1.8.9:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
and this is the content of the pom.xml file :
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
</dependencies>
Question: I don't understand this output is saying that everything is fine or there might be some incompatibility in my project, and if there are how to solve them?
If you have worked on maven in your projects for dependency management, then you must have faced one problem at least once or may be more than that. And the problem is version mismatch. It generally happens when you got some dependencies which bring it’s related dependencies together with certain version. And if you have included those dependencies with different version numbers already, they can face undesired results in compile time as well as runtime also.
Ideally to avoid above issue you need to explicitly exclude the related dependency, but it is quite possible that you can forget to do so.
To solve version mismatch issue, you can use the concept of a “bill of materials” (BOM) dependency. A BOM dependency keep track of version numbers and ensure that all dependencies (both direct and transitive) are at the same version.
How to add BOM [Bill Of Materials] dependency
Maven provides a tag dependencyManagement for this purpose. You need to add the bom information in this tag as follows. I am taking the example of Spring bom file.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
An added benefit of using the BOM is that you no longer need to specify the version attribute when depending on Spring Framework artifacts. So it will work perfectly fine.
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependencies>
Doing like above will resolve all version comparability issues and application works fine as we are not going to use unmatched versions

java.lang.NoSuchMethodError: org.codehaus.jackson.map.AnnotationIntrospector.pair

I am trying to wrok with JAX RS service. I have added few dependencies in my pom .xml. Here is the pom.
<properties>
<jersey.version>1.19</jersey.version>
</properties>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.mvel</groupId>
<artifactId>mvel2</artifactId>
<version>2.2.1.Final</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.drill.exec</groupId>
<artifactId>drill-jdbc-all</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
when i add this dependency <dependency>
<groupId>org.apache.drill.exec</groupId>
<artifactId>drill-jdbc-all</artifactId>
<version>1.1.0</version>
</dependency>
it fails with elow mentioned exception. I need the above mentioned dependecy for apache drill. On removing and running it works smooth.
The excpetion i am getting is:
java.lang.NoSuchMethodError: org.codehaus.jackson.map.AnnotationIntrospector.pair(Lorg/codehaus/jackson/map/AnnotationIn
trospector;Lorg/codehaus/jackson/map/AnnotationIntrospector;)Lorg/codehaus/jackson/map/AnnotationIntrospector;
at org.codehaus.jackson.jaxrs.MapperConfigurator._resolveIntrospectors(MapperConfigurator.java:155)
at org.codehaus.jackson.jaxrs.MapperConfigurator._setAnnotations(MapperConfigurator.java:133)
at org.codehaus.jackson.jaxrs.MapperConfigurator.getDefaultMapper(MapperConfigurator.java:70)
at org.codehaus.jackson.jaxrs.JacksonJsonProvider.locateMapper(JacksonJsonProvider.java:648)
at org.codehaus.jackson.jaxrs.JacksonJsonProvider.writeTo(JacksonJsonProvider.java:500)
at com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy.writeTo(JacksonProviderProxy.java:160)
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:302)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1510)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291).
Can some one please help as in why on adding the particular dependency it fails with the above exception.
tried running mvn dependency tree to check the conflict in jars.
Building JAXRS-JSON Maven Webapp 0.0.1-SNAPSHOT
------------------------------------------------------------------------
--- maven-dependency-plugin:2.8:tree (default-cli) # JAXRS-JSON ---
com.java.codegeeks.example:JAXRS-JSON:war:0.0.1-SNAPSHOT
+- com.sun.jersey:jersey-servlet:jar:1.19:compile
| \- com.sun.jersey:jersey-server:jar:1.19:compile
+- com.sun.jersey:jersey-json:jar:1.19:compile
| +- org.codehaus.jettison:jettison:jar:1.1:compile
| +- com.sun.xml.bind:jaxb-impl:jar:2.2.3-1:compile
| | \- javax.xml.bind:jaxb-api:jar:2.2.2:compile
| | +- javax.xml.stream:stax-api:jar:1.0-2:compile
| | \- javax.activation:activation:jar:1.1:compile
| +- org.codehaus.jackson:jackson-core-asl:jar:1.9.2:compile
| +- org.codehaus.jackson:jackson-mapper-asl:jar:1.9.2:compile
| +- org.codehaus.jackson:jackson-jaxrs:jar:1.9.2:compile
| +- org.codehaus.jackson:jackson-xc:jar:1.9.2:compile
| \- com.sun.jersey:jersey-core:jar:1.19:compile
| \- javax.ws.rs:jsr311-api:jar:1.1.1:compile
+- com.sun.jersey:jersey-client:jar:1.19:compile
+- junit:junit:jar:3.8.1:test
\- org.apache.drill.exec:drill-jdbc-all:jar:1.1.0:compile
------------------------------------------------------------------------
BUILD SUCCESS
drill contains too many packages inside it and it collides with other jars in app. I too encountered similar problem but with com.google.common.collect and org.apache.zookeeper packages of drill jar. In my case the version drill is using for these packages are older and so, I just removed those.
zip -d drill-jdbc-all-1.1.0.jar com/google/common/collect/*
zip -d drill-jdbc-all-1.1.0.jar org/apache/zookeeper/*
Now it is working fine. I am not sure how to handle all these using maven only and so opted to delete. It would be better if maven can handle that.

Using Spring 4.0 with spring-data-jpa

I am using Spring 4.0 in my JavaEE application, and I tried to use the Spring-data-jpa.
However when I add the Spring-data-jpa dependency, I found that the Spring-data-jpa will depend on Spring-3.x.
Then I wonder this will cause any problem? Since my application will have Spring-4.x with Spring-3.x.
Anyone have the same experience?
Update:
I am using Spring-data-jpg-1.4.3:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.4.3.RELEASE</version>
</dependency>
But when I run mvn dependency:tree I got this:
+- org.springframework:spring-context:jar:4.0.0.RELEASE:compile
| +- org.springframework:spring-beans:jar:4.0.0.RELEASE:compile
| +- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
| | \- commons-logging:commons-logging:jar:1.1.1:compile
| \- org.springframework:spring-expression:jar:4.0.0.RELEASE:compile
+- org.springframework:spring-aop:jar:4.0.0.RELEASE:compile
| \- aopalliance:aopalliance:jar:1.0:compile
+- org.springframework.data:spring-data-jpa:jar:1.4.3.RELEASE:compile
| +- org.springframework.data:spring-data-commons:jar:1.6.3.RELEASE:compile
| +- org.springframework:spring-orm:jar:3.1.4.RELEASE:compile
| | \- org.springframework:spring-jdbc:jar:3.1.4.RELEASE:compile
| +- org.springframework:spring-tx:jar:3.1.4.RELEASE:compile
| +- org.aspectj:aspectjrt:jar:1.7.2:compile
| +- org.slf4j:slf4j-api:jar:1.7.1:compile
| \- org.slf4j:jcl-over-slf4j:jar:1.7.1:runtime
+- org.aspectj:aspectjweaver:jar:1.7.4:compile
+- org.springframework:spring-test:jar:4.0.0.RELEASE:test
It seems that the spring 4.0.. is mixed with spring 3.1.4..
This is an error in the spring-data-jpa 1.4.3.RELEASE pom denepdency.
What actually happens is that it loads spring dependencies that exist in this maven pom instead of the ones you want to import.
The short answer is add this as a parent to your maven project:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.0.0.RC5</version>
</parent>
so that it can inherit the correct dependencies.
Another way to solve this is to use the <exclusions> tag to exclude them and then import the correct dependecies but this takes more time and is not as clean. If you don't want to add spring-boot-start-parent though, then this is how to solve this error.
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.4.1.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
...
</exclusion>
</exclusions>
</dependency>
For more info see here

Maven Transitive Dependency Issue with CXF and ACEGI

I have a pom file which originally had the following dependency:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.5.2</version>
<scope>runtime</scope>
</dependency>
According to mvn dependency:tree, the above dependency has the following transitive dependencies:
[INFO] \- org.apache.cxf:cxf-rt-transports-http:jar:2.5.2:runtime
[INFO] +- org.apache.cxf:cxf-rt-transports-common:jar:2.5.2:runtime
[INFO] \- org.springframework:spring-web:jar:3.0.6.RELEASE:runtime
[INFO] +- aopalliance:aopalliance:jar:1.0:runtime
[INFO] +- org.springframework:spring-beans:jar:3.0.6.RELEASE:runtime
[INFO] +- org.springframework:spring-context:jar:3.0.6.RELEASE:runtime
[INFO] | +- org.springframework:spring-aop:jar:3.0.6.RELEASE:runtime
[INFO] | +- org.springframework:spring-expression:jar:3.0.6.RELEASE:runtime
[INFO] | \- org.springframework:spring-asm:jar:3.0.6.RELEASE:runtime
[INFO] \- org.springframework:spring-core:jar:3.0.6.RELEASE:runtime
I then add the following dependency to my pom file:
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-cas</artifactId>
<version>1.0.3</version>
</dependency>
When I run a mvn package, it erases the spring dependencies from cxf (i.e. - spring-beans-3.0.6.RELEASE.jar, etc...) and replaces them with the 1.0 versions from the acegi plugin. If I run a dependency:tree, it now says the following:
[INFO] \- org.apache.cxf:cxf-rt-transports-http:jar:2.5.2:runtime
[INFO] \- org.apache.cxf:cxf-rt-transports-common:jar:2.5.2:runtime
How do I force maven to use the newer versions from cxf instead of the older versions from the acegi dependency? I tried adding an exclusion to the acegi dependency:
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-cas</artifactId>
<version>1.0.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
</exclusions>
</dependency>
However, when I run mvn package, I now get no spring-aop jar (it doesn't include the version needed by cxf or the version included with the acegi security).
I know that I could manually write out each of the transitive dependencies from cxf. However, is there any better approach that I could use to get maven to use the spring dependencies from cxf and not from the old acegi?
Thanks.

Resources