I am a beginner to Spring Boot/JPA. Am trying to do CRUD operation for taxi model.
I get the following error :
com.microsoft.sqlserver.jdbc.SQLServerException: Invalid column name
'taxi_id'
Any help would be highly appreciated.
This is my repository code:
package com.example.SpringBoot.Model.Repository;
import org.springframework.data.repository.CrudRepository;
import com.example.SpringBoot.Model.Taxi;
public interface DAO extends CrudRepository<Taxi, Integer>{
}
Controller
package com.example.SpringBoot.Controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.example.SpringBoot.Model.Taxi;
import com.example.SpringBoot.Model.Repository.DAO;
#RestController
public class TaxiController {
#Autowired
public DAO repo;
#PutMapping(path= "/Taxi" , produces = {"application/json"})
public Taxi insertTaxi(Taxi taxi) {
repo.save(taxi);
return taxi;
}
#DeleteMapping(path ="/Taxi/{TaxiId}")
public void deleteTaxi(#RequestParam int TaxiId) {
repo.deleteById(TaxiId);
}
#GetMapping(path ="/Taxi")
public List<Taxi> displayTaxi() {
return (List<Taxi>) repo.findAll();
}
}
Model class
package com.example.SpringBoot.Model;
import java.math.BigDecimal;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Taxi {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int TaxiId;
private String TaxiType;
public int getTaxiId() {
return TaxiId;
}
public void setTaxiId(int taxiId) {
TaxiId = taxiId;
}
public String getTaxiType() {
return TaxiType;
}
public void setTaxiType(String taxiType) {
TaxiType = taxiType;
}
}
SQL server code
CREATE TABLE [dbo].[Taxi](
[Taxiid] [int] IDENTITY(1,1) NOT NULL,
[TaxiType] [varchar](1) NOT NULL,
PRIMARY KEY CLUSTERED
(
[TaxiId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Stack trace:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.4.RELEASE)
2019-06-03 15:37:24.554 INFO 7808 --- [ main] c.e.SpringBoot.TaxiBookingApplication : Starting TaxiBookingApplication on IMCHLT080 with PID 7808 (D:\workspace\TaxiBooking\target\classes started by vignesh_nithin in D:\workspace\TaxiBooking
.............
2019-06-03 15:37:34.446 INFO 7808 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-06-03 15:37:34.456 INFO 7808 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 10 ms
2019-06-03 15:37:34.530 INFO 7808 --- [nio-8081-exec-1] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2019-06-03 15:37:34.645 WARN 7808 --- [nio-8081-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 207, SQLState: S0001
2019-06-03 15:37:34.645 ERROR 7808 --- [nio-8081-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Invalid column name 'taxi_id'.
2019-06-03 15:37:34.668 ERROR 7808 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
com.microsoft.sqlserver.jdbc.SQLServerException: Invalid column name 'taxi_id'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:259) ~[mssql-jdbc-6.4.0.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1547) ~[mssql-jdbc-6.4.0.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:548) ~[mssql-jdbc-6.4.0.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:479) ~[mssql-jdbc-6.4.0.jre8.jar:na]
I expect the Taxi table data to be displayed/inserted/deleted based on the URL being hit.
Your persistence config by default seems to translate camelcase by separating it with an underscore. So if you have:
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int TaxiId;
it will try to use: 'taxi_id';
As on db you have:
CREATE TABLE [dbo].[Taxi](
[Taxiid] [int] IDENTITY(1,1) NOT NULL,
you should either change the field name to: 'Taxiid' or explicitly name the column:
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "Taxiid")
private int TaxiId;
You may also try to change the default naming strategy used by altering accordingly these properties:
spring.jpa.hibernate.naming.implicit-strategy
spring.jpa.hibernate.naming.physical-strategy
Related
I have recently started exploring Spring boot. I am following https://www.bezkoder.com/spring-boot-jdbctemplate-postgresql-example/ documentation.
I have created all files as instructed in the documentation.
Here goes my code:
******AppApplication.java
`package com.triveni.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class AppApplication {
public static void main(String[] args) {
SpringApplication.run(AppApplication.class, args);
}
}`
***** IProductRepository *****
`package com.triveni.repository;
import com.triveni.models.ProductModel;
import java.util.List;
public interface IProductRepository {
int create(ProductModel productModel);
int update (ProductModel productModel);
ProductModel findById(int id);
List<ProductModel> findAll();
List<ProductModel> findByActive(boolean active);
}`
***** ProductModel.java *****
package com.triveni.models;
public class ProductModel {
private int productId;
private String productName;
private int cost;
private Boolean active;
private int descriptionId;
public ProductModel(int productId, String productName, int cost, Boolean active, int descriptionId){
this.productId = productId;
this.productName = productName;
this.cost = cost;
this.active = active;
this.descriptionId = descriptionId;
}
public void setProductId(int productId){
this.productId = productId;
}
public long getProductId(){
return productId;
}
public void setProductName(String productName){
this.productName = productName;
}
public String getProductName(){
return productName;
}
public void setCost(int cost) {
this.cost = cost;
}
public int getCost() {
return cost;
}
public void setActive(Boolean active) {
this.active = active;
}
public Boolean getActive() {
return active;
}
public void setDescriptionId(int descriptionId) {
this.descriptionId = descriptionId;
}
public int getDescriptionId() {
return descriptionId;
}
}
*** Product Repository *****
package com.triveni.data;
import com.triveni.models.ProductModel;
import com.triveni.repository.IProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
public class ProductRepository implements IProductRepository {
#Autowired
private JdbcTemplate jdbcTemplate;
#Override
public int create(ProductModel productModel) {
return jdbcTemplate.update("INSERT INTO public.product(\n" +
"\t\"productId\", \"productName\", cost, \"DescriptionId\", active)\n" +
"\tVALUES (?, ?, ?, ?, ?);",new Object[]{productModel.getProductId(),productModel.getProductName(),
productModel.getCost(), productModel.getDescriptionId(),productModel.getActive()});
}
#Override
public int update(ProductModel productModel) {
return 0;
}
#Override
public ProductModel findById(int id) {
return null;
}
#Override
public List<ProductModel> findAll() {
return jdbcTemplate.query("SELECT \"productId\", \"productName\", cost, \"DescriptionId\", active\n" +
"\tFROM public.product",BeanPropertyRowMapper.newInstance(ProductModel.class));
}
#Override
public List<ProductModel> findByActive(boolean active) {
return null;
}
}
***** ProductController.java *****
package com.triveni.controllers;
import java.util.ArrayList;
import java.util.List;
import com.triveni.data.ProductRepository;
import com.triveni.models.ProductModel;
import com.triveni.repository.IProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/api/v1")
public class ProductController {
#Autowired
ProductRepository productRepository;
#GetMapping("/product")
public ResponseEntity<List<ProductModel>> getAllProducts(){
try{
List<ProductModel> products = new ArrayList<ProductModel>();
productRepository.findAll().forEach(products::add);;
return new ResponseEntity<>(products, HttpStatus.OK);
}catch (Exception e){
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
My Project Folder Structure
I am getting following error
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Dec 27 13:51:39 IST 2022
There was an unexpected error (type=Not Found, status=404).
Any help will be highly appreciated.
*Output
/Users/chhayatiwari/Library/Java/JavaVirtualMachines/openjdk-19.0.1/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=51857:/Applications/IntelliJ IDEA CE.app/Contents/bin -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath /Users/chhayatiwari/Desktop/Work/TriveniApp-Service/app/target/classes:/Users/chhayatiwari/.m2/repository/org/springframework/boot/spring-boot-starter-web/3.0.1/spring-boot-starter-web-3.0.1.jar:/Users/chhayatiwari/.m2/repository/org/springframework/boot/spring-boot-starter/3.0.1/spring-boot-starter-3.0.1.jar:/Users/chhayatiwari/.m2/repository/org/springframework/boot/spring-boot/3.0.1/spring-boot-3.0.1.jar:/Users/chhayatiwari/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/3.0.1/spring-boot-autoconfigure-3.0.1.jar:/Users/chhayatiwari/.m2/repository/org/springframework/boot/spring-boot-starter-logging/3.0.1/spring-boot-starter-logging-3.0.1.jar:/Users/chhayatiwari/.m2/repository/ch/qos/logback/logback-classic/1.4.5/logback-classic-1.4.5.jar:/Users/chhayatiwari/.m2/repository/ch/qos/logback/logback-core/1.4.5/logback-core-1.4.5.jar:/Users/chhayatiwari/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.19.0/log4j-to-slf4j-2.19.0.jar:/Users/chhayatiwari/.m2/repository/org/apache/logging/log4j/log4j-api/2.19.0/log4j-api-2.19.0.jar:/Users/chhayatiwari/.m2/repository/org/slf4j/jul-to-slf4j/2.0.6/jul-to-slf4j-2.0.6.jar:/Users/chhayatiwari/.m2/repository/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar:/Users/chhayatiwari/.m2/repository/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar:/Users/chhayatiwari/.m2/repository/org/springframework/boot/spring-boot-starter-json/3.0.1/spring-boot-starter-json-3.0.1.jar:/Users/chhayatiwari/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.14.1/jackson-databind-2.14.1.jar:/Users/chhayatiwari/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.14.1/jackson-annotations-2.14.1.jar:/Users/chhayatiwari/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.14.1/jackson-core-2.14.1.jar:/Users/chhayatiwari/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.14.1/jackson-datatype-jdk8-2.14.1.jar:/Users/chhayatiwari/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.14.1/jackson-datatype-jsr310-2.14.1.jar:/Users/chhayatiwari/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.14.1/jackson-module-parameter-names-2.14.1.jar:/Users/chhayatiwari/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/3.0.1/spring-boot-starter-tomcat-3.0.1.jar:/Users/chhayatiwari/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/10.1.4/tomcat-embed-core-10.1.4.jar:/Users/chhayatiwari/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/10.1.4/tomcat-embed-el-10.1.4.jar:/Users/chhayatiwari/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/10.1.4/tomcat-embed-websocket-10.1.4.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-web/6.0.3/spring-web-6.0.3.jar:/Users/chhayatiwari/.m2/repository/io/micrometer/micrometer-observation/1.10.2/micrometer-observation-1.10.2.jar:/Users/chhayatiwari/.m2/repository/io/micrometer/micrometer-commons/1.10.2/micrometer-commons-1.10.2.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-webmvc/6.0.3/spring-webmvc-6.0.3.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-aop/6.0.3/spring-aop-6.0.3.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-context/6.0.3/spring-context-6.0.3.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-expression/6.0.3/spring-expression-6.0.3.jar:/Users/chhayatiwari/.m2/repository/org/slf4j/slf4j-api/2.0.6/slf4j-api-2.0.6.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-core/6.0.3/spring-core-6.0.3.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-jcl/6.0.3/spring-jcl-6.0.3.jar:/Users/chhayatiwari/.m2/repository/org/springframework/boot/spring-boot-starter-data-jdbc/3.0.1/spring-boot-starter-data-jdbc-3.0.1.jar:/Users/chhayatiwari/.m2/repository/org/springframework/boot/spring-boot-starter-jdbc/3.0.1/spring-boot-starter-jdbc-3.0.1.jar:/Users/chhayatiwari/.m2/repository/com/zaxxer/HikariCP/5.0.1/HikariCP-5.0.1.jar:/Users/chhayatiwari/.m2/repository/org/springframework/data/spring-data-jdbc/3.0.0/spring-data-jdbc-3.0.0.jar:/Users/chhayatiwari/.m2/repository/org/springframework/data/spring-data-relational/3.0.0/spring-data-relational-3.0.0.jar:/Users/chhayatiwari/.m2/repository/org/springframework/data/spring-data-commons/3.0.0/spring-data-commons-3.0.0.jar:/Users/chhayatiwari/.m2/repository/org/postgresql/postgresql/42.5.1/postgresql-42.5.1.jar:/Users/chhayatiwari/.m2/repository/org/checkerframework/checker-qual/3.5.0/checker-qual-3.5.0.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-jdbc/5.3.22/spring-jdbc-5.3.22.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-beans/6.0.3/spring-beans-6.0.3.jar:/Users/chhayatiwari/.m2/repository/org/springframework/spring-tx/6.0.3/spring-tx-6.0.3.jar com.triveni.app.AppApplication
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.1)
2022-12-27T20:17:11.351+05:30 INFO 3695 --- [ main] com.triveni.app.AppApplication : Starting AppApplication using Java 19.0.1 with PID 3695 (/Users/chhayatiwari/Desktop/Work/TriveniApp-Service/app/target/classes started by chhayatiwari in /Users/chhayatiwari/Desktop/Work/TriveniApp-Service/app)
2022-12-27T20:17:11.353+05:30 INFO 3695 --- [ main] com.triveni.app.AppApplication : No active profile set, falling back to 1 default profile: "default"
2022-12-27T20:17:11.664+05:30 INFO 3695 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2022-12-27T20:17:11.671+05:30 INFO 3695 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 JDBC repository interfaces.
2022-12-27T20:17:11.919+05:30 INFO 3695 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-12-27T20:17:11.924+05:30 INFO 3695 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-12-27T20:17:11.925+05:30 INFO 3695 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.4]
2022-12-27T20:17:11.972+05:30 INFO 3695 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-12-27T20:17:11.973+05:30 INFO 3695 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 589 ms
2022-12-27T20:17:12.162+05:30 INFO 3695 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-12-27T20:17:12.282+05:30 INFO 3695 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection#6680f714
2022-12-27T20:17:12.283+05:30 INFO 3695 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2022-12-27T20:17:12.343+05:30 INFO 3695 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-12-27T20:17:12.348+05:30 INFO 3695 --- [ main] com.triveni.app.AppApplication : Started AppApplication in 1.206 seconds (process running for 1.435)
2022-12-27T20:19:18.599+05:30 INFO 3695 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-12-27T20:19:18.599+05:30 INFO 3695 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-12-27T20:19:18.604+05:30 INFO 3695 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 5 ms
try to add this to annotation #CrossOrigin("*") after #RestController.
I believe you are just launching the spring application and on launch, this error shows up. In order to test your URL you can type
<YOUR-URL>/app/v1/product
This should return you the Response you are looking for.
Remove ResponseEntity<List> from method and instead return a simple String and check if the method invoked or not. If it works properly then go to the next step and invoke the repository.
I am trying to add a prefix or suffix in the controller at the method level on top of GET, POST, PUT, DELETE mappings.
Controller class
#RestController
#RequestMapping("/something")
public class SomeController {
#PutMapping("/some/path/")
public ResponseEntity<ApiResponse<String>> someMethod() {
....
}
...
}
So, basically, the above request URL should be something like : http://localhost:8080/something/some/path/
Now, I just want to add some prefix or suffix whatever is feasible to the request URL which will be something like : http://localhost:8080/something/read/some/path/ or http://localhost:8080/something/some/path/read/ the extra "/read" which needs to be added to the request URL as a prefix or suffix. I can do this directly by adding this to the PutMapping value, but I want to decorate it somewhat using annotation like #Read
So, the updated Controller class will be like
#RestController
#RequestMapping("/something")
public class SomeController {
#Read
#PutMapping("/some/path/")
public ResponseEntity<ApiResponse<String>> someMethod() {
....
}
...
}
and the same way updated request URL will be like : http://localhost:8080/something/read/some/path/
I am unable to find a better way to do this. Till now I have only achieved adding a class-level prefix using custom annotation.
Can anyone please help with the above requirement.?
Thank you !!
I am also curious to know whether is achievable or not even?
Using such way of path extension make your code less understandable. (maybe you should read more about RESTful API) But spring can do almost everything you want.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.stream.Stream;
#SpringBootApplication
public class DemoApplication {
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Read {
}
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Write {
}
#Bean
public WebMvcRegistrations webMvcRegistrations() {
return new WebMvcRegistrations() {
#Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new RequestMappingHandlerMapping() {
#Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo defaultRequestMappingInfo = super.getMappingForMethod(method, handlerType);
if (defaultRequestMappingInfo == null) {
return null;
}
String pathSuffix;
if (method.isAnnotationPresent(Read.class)) {
pathSuffix = "read";
} else if (method.isAnnotationPresent(Write.class)) {
pathSuffix = "write";
} else {
return defaultRequestMappingInfo;
}
//extend path by mutating configured request mapping info
RequestMappingInfo.Builder mutateBuilder = defaultRequestMappingInfo.mutate();
mutateBuilder.paths(
defaultRequestMappingInfo.getPatternValues().stream()
.map(path -> path + "/" + pathSuffix)
.toArray(String[]::new)
);
return mutateBuilder.build();
}
};
}
};
}
#RestController
#RequestMapping("/books")
public static class BooksController {
#Read
#GetMapping("/{id}")
public String readBook(#PathVariable("id") String bookId) {
return bookId;
}
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Extension point is here, you can change path like you want.
Example:
request: http://localhost:8080/books/asd
response: 404
output:
2022-06-27 10:49:48.671 DEBUG 8300 --- [nio-8080-exec-2] com.example.demo.DemoApplication$1$1 : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
request: http://localhost:8080/books/asd/read
response: asd
output:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.0)
2022-06-27 10:48:53.622 INFO 8300 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 1.8.0_312 on DESKTOP with PID 8300 ()
2022-06-27 10:48:53.624 DEBUG 8300 --- [ main] com.example.demo.DemoApplication : Running with Spring Boot v2.7.0, Spring v5.3.20
2022-06-27 10:48:53.625 INFO 8300 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2022-06-27 10:48:54.227 INFO 8300 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-06-27 10:48:54.233 INFO 8300 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-06-27 10:48:54.233 INFO 8300 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.63]
2022-06-27 10:48:54.298 INFO 8300 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-06-27 10:48:54.298 INFO 8300 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 643 ms
2022-06-27 10:48:54.473 DEBUG 8300 --- [ main] com.example.demo.DemoApplication$1$1 : 3 mappings in 'requestMappingHandlerMapping'
2022-06-27 10:48:54.536 INFO 8300 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-06-27 10:48:54.543 INFO 8300 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.199 seconds (JVM running for 1.827)
2022-06-27 10:49:01.196 INFO 8300 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-06-27 10:49:01.196 INFO 8300 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-06-27 10:49:01.197 INFO 8300 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2022-06-27 10:49:01.210 DEBUG 8300 --- [nio-8080-exec-1] com.example.demo.DemoApplication$1$1 : Mapped to com.example.demo.DemoApplication$BooksController#readBook(String)
dependencies
org.springframework.boot:spring-boot-starter-web
application.properties
logging.level.com.example.demo=debug
I'm getting an error when I try to start Spring Boot using a Java bean mapper. I'm using Eclipse on Windows, Gradle to build. This is just a learning project I'm using to learn these components.
I'm listening to an ActiveMQ Artemis queue, using the incoming data to call a web service, then saving the order response in a MondoDB. All the components are working with the exception of the mapper converting the api response to a MongoDB entity.
Can anyone see what I'm doing wrong here? It's something with how I'm injecting the OrderMapper, but I'm not sure at this point. This is the Spring output:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.5)
2021-04-30 14:16:15.860 INFO 2320 --- [ main] c.b.R.RestClientPocApplication : Starting RestClientPocApplication using Java 11.0.9 on PSPLT-F7VYYY2 with PID 2320 (C:\Users\Bwarrick\Workspaces\Java\RESTClientPOC\bin\main started by Bwarrick in C:\Users\Bwarrick\Workspaces\Java\RESTClientPOC)
2021-04-30 14:16:15.863 INFO 2320 --- [ main] c.b.R.RestClientPocApplication : No active profile set, falling back to default profiles: default
2021-04-30 14:16:16.405 INFO 2320 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
2021-04-30 14:16:16.567 INFO 2320 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 157 ms. Found 1 MongoDB repository interfaces.
2021-04-30 14:16:16.991 INFO 2320 --- [ main] org.mongodb.driver.cluster : Cluster created with settings {hosts=[192.168.56.102:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'}
2021-04-30 14:16:17.064 INFO 2320 --- [68.56.102:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:1, serverValue:49}] to 192.168.56.102:27017
2021-04-30 14:16:17.064 INFO 2320 --- [68.56.102:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:2, serverValue:50}] to 192.168.56.102:27017
2021-04-30 14:16:17.065 INFO 2320 --- [68.56.102:27017] org.mongodb.driver.cluster : Monitor thread successfully connected to server with description ServerDescription{address=192.168.56.102:27017, type=STANDALONE, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=9, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=23420200}
2021-04-30 14:16:17.332 WARN 2320 --- [ main] onfigReactiveWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'artemisConsumer' defined in file [C:\Users\Bwarrick\Workspaces\Java\RESTClientPOC\bin\main\com\benwarrick\RESTClientPOC\jms\ArtemisConsumer.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.benwarrick.RESTClientPOC.service.OrderMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2021-04-30 14:16:17.355 INFO 2320 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-04-30 14:16:17.370 ERROR 2320 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 1 of constructor in com.benwarrick.RESTClientPOC.jms.ArtemisConsumer required a bean of type 'com.benwarrick.RESTClientPOC.service.OrderMapper' that could not be found.
Action:
Consider defining a bean of type 'com.benwarrick.RESTClientPOC.service.OrderMapper' in your configuration.
Here is my component:
package com.benwarrick.RESTClientPOC.jms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import com.benwarrick.RESTClientPOC.persistance.OrderEntity;
import com.benwarrick.RESTClientPOC.persistance.OrderRepository;
import com.benwarrick.RESTClientPOC.service.CoinBaseClientServiceImpl;
import com.benwarrick.RESTClientPOC.service.OrderMapper;
import com.benwarrick.RESTClientPOC.service.OrderResponse;
import com.benwarrick.RESTClientPOC.service.Price;
import com.benwarrick.RESTClientPOC.service.Prices;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Flux;
#Component
public class ArtemisConsumer {
private final OrderRepository orderRepository;
private final OrderMapper orderMapper;
#Autowired
public ArtemisConsumer(OrderRepository orderRepository, OrderMapper orderMapper) {
this.orderRepository = orderRepository;
this.orderMapper = orderMapper;
}
#JmsListener(destination = "test.topic::test.queue")
public void receive(String msg){
System.out.println("Got Message: " + msg);
CoinBaseClientServiceImpl client = new CoinBaseClientServiceImpl();
Mono<OrderResponse>orderCreate = client.createOrder("market", "USD", "BTC", "5");
orderCreate.log().subscribe(
successValue -> processResponse(successValue),
error -> System.err.println(error.getMessage()),
() -> System.out.println("mono consumed")
);
}
public void processResponse(OrderResponse orderResponse) {
System.out.println(orderResponse.getOrderID() + " " + orderResponse.getSellingCurrency() + orderResponse.getBuyingCurrency() + " Qty: "
+ orderResponse.getBoughtQty() + " Type: " + orderResponse.getOrderType()) ;
try {
OrderEntity entity = orderMapper.apiResponseToEntity(orderResponse);
OrderEntity newEntity = orderRepository.save(entity);
System.out.println("Test: " + newEntity.getBoughtQuantity());
}
catch(Exception e) {
System.out.println("Exception: " + e.toString()) ;
}
}
}
Here is my main process:
package com.benwarrick.RESTClientPOC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
#SpringBootApplication
#EnableAsync
public class RestClientPocApplication {
private static final Logger LOG = LoggerFactory.getLogger(RestClientPocApplication.class);
public static void main(String[] args) {
ConfigurableApplicationContext ctx =
SpringApplication.run(RestClientPocApplication.class, args);
String mongoDBHost = ctx.getEnvironment().getProperty("spring.data.mongodb.host");
String mongoDbPort = ctx.getEnvironment().getProperty("spring.data.mongodb.port");
LOG.info("Connected to MongoDb: " + mongoDBHost + ":" + mongoDbPort);
}
}
And here is the bean that isn't being found:
package com.benwarrick.RESTClientPOC.service;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import com.benwarrick.RESTClientPOC.persistance.OrderEntity;
#Mapper (componentModel = "spring")
public interface OrderMapper {
#Mappings({
#Mapping(target = "id", ignore = true),
#Mapping(target = "version", ignore = true),
#Mapping(target = "orderId", source="orderID"),
#Mapping(target = "orderID", source="boughtQty")
})
OrderEntity apiResponseToEntity(OrderResponse api);
}
And my build.graddle
plugins {
id 'org.springframework.boot' version '2.4.5'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.benwarrick'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
ext {
mapstructVersion = "1.4.2.Final"
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-artemis'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
implementation("org.mapstruct:mapstruct:${mapstructVersion}")
compileOnly "org.mapstruct:mapstruct-processor:${mapstructVersion}"
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"
testAnnotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"
implementation('org.springframework.boot:spring-boot-starter-data-mongodb')
testImplementation('de.flapdoodle.embed:de.flapdoodle.embed.mongo')
}
test {
useJUnitPlatform()
}
For MapStruct you need to correctly set up annotation processor so that IDE (Eclipse in your case) and build tool, Gradle that is play well together.
You can read on MapStruct page uder IDE support about it. Now I didn't manage to get it working without issues that way.
Plugin to the rescue! Now what I recommend you is that you use following Gradle plugin that can set up Eclipse IDE in a proper way for you. The plugin: https://plugins.gradle.org/plugin/com.diffplug.eclipse.apt
I see you know already how to include the plugin, just in case the code that you have to add to build.gradle:
plugins {
...
id 'com.diffplug.eclipse.apt' version "3.29.1"
}
And then run the command from your project that will set up Eclipse:
./gradlew eclipseJdtApt eclipseFactorypath eclipseJdt
From within Eclipse, you now have to run right-click the project and select Gradle / Refresh Gradle Project.
Afterwards, Project / Clean. With this clean build, the annotation-processor should be running.
I hope Eclipse Buildship will pick this up and make it easier to support his feature.
can anyone help me please to fix this proble, iwant to generate automaticallly with jpa my table in sql , i can't see any problem in my work .. i did many projects but it is always the same proble. I dont receive any error but the table also doesnt want to create in my database
So this is my application.properties :
server.port=8285
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=
### JPA / HIBERNATE ###
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect ```
My Entity:
package com.entite;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table( name = "T_EMPLOYEE")
public class Product implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="EMPL_ID")
private long id;
#Column(name="EMPLi_name")
private String name;
private String role;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Product(String name, String role) {
this.name = name;
this.role = role;
}
public Product() {}
#Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", role=" + role + "]";
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((role == null) ? 0 : role.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Product other = (Product) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (role == null) {
if (other.role != null)
return false;
} else if (!role.equals(other.role))
return false;
return true;
}
}
JPARepository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.entite.Product;
#Repository
public interface ProductRepository extends JpaRepository<Product, Long>{
}
###This is what it says ###
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.2)
2021-01-17 15:34:45 - INFO - com.salon.Application - Starting Application using Java 1.8.0_271 on LAPTOP-7C6GGTA9 with PID 22672 (C:\Users\zizoe\eclipse-workspace\SpringBoot\target\classes started by zizoe in C:\Users\zizoe\eclipse-workspace\SpringBoot)
2021-01-17 15:34:45 - INFO - com.salon.Application - No active profile set, falling back to default profiles: default
2021-01-17 15:34:46 - INFO - o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-01-17 15:34:46 - INFO - o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 6 ms. Found 0 JPA repository interfaces.
2021-01-17 15:34:47 - INFO - o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8285 (http)
2021-01-17 15:34:47 - INFO - o.a.catalina.core.StandardService - Starting service [Tomcat]
2021-01-17 15:34:47 - INFO - o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-01-17 15:34:47 - INFO - o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2021-01-17 15:34:47 - INFO - o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1301 ms
2021-01-17 15:34:47 - INFO - o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2021-01-17 15:34:47 - INFO - org.hibernate.Version - HHH000412: Hibernate ORM core version 5.4.27.Final
2021-01-17 15:34:47 - INFO - o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-01-17 15:34:47 - INFO - com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2021-01-17 15:34:48 - INFO - com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2021-01-17 15:34:48 - INFO - org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
2021-01-17 15:34:48 - INFO - o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-01-17 15:34:48 - INFO - o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-01-17 15:34:48 - WARN - o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration - 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 warning
2021-01-17 15:34:48 - INFO - o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
2021-01-17 15:34:48 - INFO - o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8285 (http) with context path ''
2021-01-17 15:34:48 - INFO - com.salon.Application - Started Application in 3.431 seconds (JVM running for 4.228)
I do appreciate if you guys helps :(
Replace
spring.jpa.hibernate.ddl-auto=update
With
spring.jpa.hibernate.hbm2ddl.auto=update
Can you try including below properties also?
spring.datasource.initialization-mode=always
spring.jpa.generate-ddl=true
Can u try adding this to Main Class?
#EntityScan("org.example.base.entities")
where org.example.base.entities is the package name for entities, in your case it can be anything
Today I encountered a NullPointExcepiton When I tried to use an AOP Logger in java to print logs of a class which contains a BiPredicate(FuncionalInterface).
Problem:
Is there any wrong usage of FunctionalInterface with AOP?
When I set the pointCut to BiPredicateExample.java, the exception will
be raised by biPredicateExample.cmp(FuntionalInterface), while the
method in this class works fun(biPredicateExample.cmp1()).
The NullPointExcepiton can be reproduced using following codes:
Github repository link here
com/test/BiPredicateExample.java
import org.springframework.stereotype.Component;
import java.util.function.BiPredicate;
#Component
public class BiPredicateExample {
public BiPredicate<Integer,Integer> cmp = (x,y) -> (x>y);
public boolean cmp1(Integer x, Integer y){
return x>y;
}
}
com/logger/BiPredicateExample.java
package com.logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
#Aspect
#Component
public class LogAspect {
/**
* BiPredicateExample works fine.
*/
// #Pointcut("execution(* com.empty.*.*(..) )")
/**
* It'll raise NullPointException When this PointCut cut
* into the FunctionalInterface.
*/
#Pointcut("execution(* com.test.*.*(..) )")
public void logPointCut(){}
#Before("logPointCut()")
public void printBeforeMethodInvoke(JoinPoint joinPoint){
}
}
com/Application.java
package com;
import com.test.BiPredicateExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application implements CommandLineRunner{
#Autowired
BiPredicateExample biPredicateExample;
public static void main(String[]args){
SpringApplication.run(Application.class,args);
}
#Override
public void run(String... strings) throws Exception {
boolean w=biPredicateExample.cmp1(10,2);
System.out.println(w);
boolean f=biPredicateExample.cmp.test(10,2);
System.out.println(f);
}
}
Thanks!
my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>AOP_FunctionalInterface_Test</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
</dependencies>>
</project>
The problem is that the member variable cmp only has a meaningful value in the original class, but as soon as you use Spring AOP, you are actually interacting with a dynamic proxy object. JDK dynamic proxies, however, only proxy public method calls (CGLIB ones also protected and package-scoped methods). There is no proxying mechanism for member variables, you need to make sure that you do not directly access internal state via member access from outside but e.g. via getter method.
I.e. in this case you change biPredicateExample.cmp into biPredicateExample.getCmp(), that's all:
package com.test;
import org.springframework.stereotype.Component;
import java.util.function.BiPredicate;
#Component
public class BiPredicateExample {
private BiPredicate<Integer, Integer> cmp = (x, y) -> (x > y);
public boolean cmp1(Integer x, Integer y) {
return x > y;
}
public BiPredicate<Integer, Integer> getCmp() {
return cmp;
}
}
package com;
import com.test.BiPredicateExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application implements CommandLineRunner {
#Autowired
BiPredicateExample biPredicateExample;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... strings) throws Exception {
System.out.println(biPredicateExample.cmp1(10, 2));
System.out.println(biPredicateExample.getCmp().test(10, 2));
}
}
package com.logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
#Aspect
#Component
public class LogAspect {
#Pointcut("execution(* com.test..*(..) )")
public void logPointCut() {}
#Before("logPointCut()")
public void printBeforeMethodInvoke(JoinPoint joinPoint) {
System.out.println(joinPoint);
}
}
Then the console log changes into:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.3.RELEASE)
2018-06-16 14:15:10.040 INFO 12456 --- [ main] com.Application : Starting Application on Xander-Ultrabook with PID 12456 (C:\Users\alexa\Documents\java-src\AOP_FunctionalInterface_Test\target\classes started by alexa in C:\Users\alexa\Documents\java-src\AOP_FunctionalInterface_Test)
2018-06-16 14:15:10.056 INFO 12456 --- [ main] com.Application : No active profile set, falling back to default profiles: default
2018-06-16 14:15:10.118 INFO 12456 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#3c87521: startup date [Sat Jun 16 14:15:10 ICT 2018]; root of context hierarchy
2018-06-16 14:15:11.437 INFO 12456 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-06-16 14:15:11.452 INFO 12456 --- [ main] com.Application : Started Application in 1.724 seconds (JVM running for 2.524)
execution(boolean com.test.BiPredicateExample.cmp1(Integer,Integer))
true
execution(BiPredicate com.test.BiPredicateExample.getCmp())
true
2018-06-16 14:15:11.452 INFO 12456 --- [ Thread-5] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#3c87521: startup date [Sat Jun 16 14:15:10 ICT 2018]; root of context hierarchy
2018-06-16 14:15:11.531 INFO 12456 --- [ Thread-5] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
Process finished with exit code 0