Hello I'm new to Java and Spring itself. Now I'm studying JPA, in general, the question is this: Why does Hibernate look for the last_name column in BaseEntity when I have this column in my drivers?
All this happens when I try to call findAll and create a query with the concept of dateTable
Progect in Git Hub: https://github.com/Slizzardd/nix_10/tree/master/hw_9_web_jpa
Error:
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [last_name] on this ManagedType [ua.com.alevel.persistence.entity.BaseEntity]
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.checkNotNull(AbstractManagedType.java:148)
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:119)
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:117)
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:44)
at org.hibernate.query.criteria.internal.path.AbstractFromImpl.locateAttributeInternal(AbstractFromImpl.java:111)
at org.hibernate.query.criteria.internal.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:204)
at org.hibernate.query.criteria.internal.path.AbstractPathImpl.get(AbstractPathImpl.java:177)
at ua.com.alevel.persistence.dao.impl.DriverDaoImpl.findAll(DriverDaoImpl.java:90)
at ua.com.alevel.persistence.dao.impl.DriverDaoImpl$$FastClassBySpringCGLIB$$70e9ea23.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
at ua.com.alevel.persistence.dao.impl.DriverDaoImpl$$EnhancerBySpringCGLIB$$3de59a25.findAll(<generated>)
at ua.com.alevel.service.impl.DriverServiceImpl.findAll(DriverServiceImpl.java:60)
at ua.com.alevel.facade.impl.DriverFacadeImpl.findAll(DriverFacadeImpl.java:64)
at ua.com.alevel.view.controller.DriverController.findAll(DriverController.java:41)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
My BaseEntity:
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Temporal(TemporalType.TIMESTAMP)
private Date updated;
private Boolean visible;
@Column(name = "image_url")
private String imageUrl;
public BaseEntity() {
this.created = new Date();
this.updated = new Date();
this.visible = true;
}
@PreUpdate
public void preUpdate() {
this.updated = new Date();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
public Boolean getVisible() {
return visible;
}
public void setVisible(Boolean visible) {
this.visible = visible;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
My Driver:
@Entity
@Table(name = "drivers")
public class Driver extends BaseEntity {
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
private String notes;
private double balance;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
name = "driver_car",
joinColumns = @JoinColumn(name = "driver_id"),
inverseJoinColumns = @JoinColumn(name = "car_id"))
private Set<Car> cars;
public Driver() {
super();
this.cars = new HashSet<>();
}
public Set<Car> getCars() {
return cars;
}
public void setCars(Set<Car> cars) {
this.cars = cars;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
methodFindAll in DriverDaoImpl:
@Override
public DataTableResponse<Driver> findAll(DataTableRequest request) throws Exception {
List<Driver> drivers;
Map<Object, Object> otherParamMap = new HashMap<>();
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Driver> criteriaQuery = criteriaBuilder.createQuery(Driver.class);
Root<Driver> from = criteriaQuery.from(Driver.class);
int page = (request.getCurrentPage() - 1) * request.getPageSize();
int size = page request.getPageSize();
if(request.getSort().equals("carCount")){
Query query;
if (request.getOrder().equals("desc")) {
query = entityManager.createQuery("select d from Driver d where d.visible = true order by d.cars.size desc")
.setFirstResult(page)
.setMaxResults(size);
} else {
query = entityManager.createQuery("select d from Driver d where d.visible = true order by d.cars.size asc")
.setFirstResult(page)
.setMaxResults(size);
}
drivers = query.getResultList();
}else {
try{
if (request.getOrder().equals("desc")) {
criteriaQuery.orderBy(criteriaBuilder.desc(from.get(request.getSort())));
} else {
criteriaQuery.orderBy(criteriaBuilder.asc(from.get(request.getSort())));
}
}catch (Exception e){
e.printStackTrace();;
}
drivers = entityManager.createQuery(criteriaQuery)
.setFirstResult(page)
.setMaxResults(size)
.getResultList();
}
for (int i = 0; i < drivers.size(); i ) {
otherParamMap.put(drivers.get(i).getId(), countNumOfCars(drivers.get(i).getId()));
}
DataTableResponse<Driver> response = new DataTableResponse<>();
response.setSort(request.getSort());
response.setOrder(request.getOrder());
response.setCurrentPage(request.getCurrentPage());
response.setCurrentSize(request.getPageSize());
response.setItems(drivers);
response.setOtherParamMap(otherParamMap);
return response;
}
private int countNumOfCars(Long id) {
return findById(id).getCars().size();
}
My Hibernate Config:
@Configuration
@EnableTransactionManagement
public class HibernateConfig {
@Value("${spring.datasource.url}")
private String jdbcUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driver-class-name}")
private String driver;
@Value("${spring.jpa.properties.hibernate.dialect}")
private String dialect;
@Value("${spring.jpa.hibernate.ddl-auto}")
private String hbm2ddl;
@Value("${spring.jpa.show-sql}")
private Boolean showSql;
@Value("${spring.jpa.properties.hibernate.jdbc.max_size}")
private String maxSize;
@Value("${spring.jpa.properties.hibernate.jdbc.min_size}")
private String minSize;
@Value("${spring.jpa.properties.hibernate.jdbc.batch_size}")
private String batchSize;
@Value("${spring.jpa.properties.hibernate.jdbc.fetch_size}")
private String fetchSize;
@Value("${spring.jpa.properties.hibernate.enable_lazy_load_no_trans}")
private String lazyLoad;
private static final String HIBERNATE_DIALECT = "hibernate.dialect";
private static final String HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
private static final String HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String HIBERNATE_ENABLE_LAZY_LOAD_NO_TRANS = "hibernate.enable_lazy_load_no_trans";
private static final String MAX_SIZE = "hibernate.c3p0.max_size";
private static final String MIN_SIZE = "hibernate.c3p0.min_size";
private static final String BATCH_SIZE = "hibernate.jdbc.batch_size";
private static final String FETCH_SIZE = "hibernate.jdbc.fetch_size";
private static final String ENTITY_MANAGER_PACKAGES_TO_SCAN = "ua.com.alevel.persistence.entity";
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager manager = new HibernateTransactionManager();
manager.setSessionFactory(sessionFactoryBean().getObject());
return manager;
}
@Bean
public LocalSessionFactoryBean sessionFactoryBean() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(ENTITY_MANAGER_PACKAGES_TO_SCAN);
sessionFactoryBean.setHibernateProperties(hibernateProperties());
try {
sessionFactoryBean.afterPropertiesSet();
} catch (IOException e) {
e.printStackTrace();
}
return sessionFactoryBean;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put(HIBERNATE_DIALECT, dialect);
properties.put(HIBERNATE_HBM2DDL_AUTO, hbm2ddl);
properties.put(HIBERNATE_SHOW_SQL, showSql);
properties.put(HIBERNATE_ENABLE_LAZY_LOAD_NO_TRANS, lazyLoad);
properties.put(MAX_SIZE, maxSize);
properties.put(MIN_SIZE, minSize);
properties.put(BATCH_SIZE, batchSize);
properties.put(FETCH_SIZE, fetchSize);
return properties;
}
}
My application.properties:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/taxi_bd?useSSL=false&serverTimezone=UTC&createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.platform=mysql
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.jdbc.fetch_size=50
spring.jpa.properties.hibernate.jdbc.max_size=25
spring.jpa.properties.hibernate.jdbc.min_size=10
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
My MainApplication:
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class })
public class WebJpaApplication {
public static void main(String[] args) {
SpringApplication.run(WebJpaApplication.class, args);
}
}
CodePudding user response:
The solution may not be so good, but I decided to just add an if else to the function and here is the function before:
@Override
public DataTableResponse<Driver> findAll(DataTableRequest request) throws Exception {
List<Driver> drivers;
Map<Object, Object> otherParamMap = new HashMap<>();
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Driver> criteriaQuery = criteriaBuilder.createQuery(Driver.class);
Root<Driver> from = criteriaQuery.from(Driver.class);
int page = (request.getCurrentPage() - 1) * request.getPageSize();
int size = page request.getPageSize();
if(request.getSort().equals("carCount")){
Query query;
if (request.getOrder().equals("desc")) {
query = entityManager.createQuery("select d from Driver d where d.visible = true order by d.cars.size desc")
.setFirstResult(page)
.setMaxResults(size);
} else {
query = entityManager.createQuery("select d from Driver d where d.visible = true order by d.cars.size asc")
.setFirstResult(page)
.setMaxResults(size);
}
drivers = query.getResultList();
}else {
try{
if (request.getOrder().equals("desc")) {
criteriaQuery.orderBy(criteriaBuilder.desc(from.get(request.getSort())));
} else {
criteriaQuery.orderBy(criteriaBuilder.asc(from.get(request.getSort())));
}
}catch (Exception e){
e.printStackTrace();;
}
drivers = entityManager.createQuery(criteriaQuery)
.setFirstResult(page)
.setMaxResults(size)
.getResultList();
}
for (int i = 0; i < drivers.size(); i ) {
otherParamMap.put(drivers.get(i).getId(), countNumOfCars(drivers.get(i).getId()));
}
DataTableResponse<Driver> response = new DataTableResponse<>();
response.setSort(request.getSort());
response.setOrder(request.getOrder());
response.setCurrentPage(request.getCurrentPage());
response.setCurrentSize(request.getPageSize());
response.setItems(drivers);
response.setOtherParamMap(otherParamMap);
return response;
}
private int countNumOfCars(Long id) {
return findById(id).getCars().size();
}
after:
@Override
public DataTableResponse<Driver> findAll(DataTableRequest request) throws Exception {
List<Driver> drivers;
Map<Object, Object> otherParamMap = new HashMap<>();
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Driver> criteriaQuery = criteriaBuilder.createQuery(Driver.class);
Root<Driver> from = criteriaQuery.from(Driver.class);
int page = (request.getCurrentPage() - 1) * request.getPageSize();
int size = page request.getPageSize();
if (request.getSort().equals("carCount")) {
Query query;
if (request.getOrder().equals("desc")) {
query = entityManager.createQuery("select d from Driver d where d.visible = true order by d.cars.size desc")
.setFirstResult(page)
.setMaxResults(size);
} else {
query = entityManager.createQuery("select d from Driver d where d.visible = true order by d.cars.size asc")
.setFirstResult(page)
.setMaxResults(size);
}
drivers = query.getResultList();
} else if (request.getSort().equals("first_name") || request.getSort().equals("last_name")) {
Query query;
if (request.getOrder().equals("desc")) {
query = entityManager.createQuery("select d from Driver d where d.visible = true order by " request.getSort() " desc")
.setFirstResult(page)
.setMaxResults(size);
} else {
query = entityManager.createQuery("select d from Driver d where d.visible = true order by " request.getSort() " asc")
.setFirstResult(page)
.setMaxResults(size);
}
drivers = query.getResultList();
} else {
try {
if (request.getOrder().equals("desc")) {
criteriaQuery.orderBy(criteriaBuilder.desc(from.get(request.getSort())));
} else {
criteriaQuery.orderBy(criteriaBuilder.asc(from.get(request.getSort())));
}
} catch (Exception e) {
e.printStackTrace();
;
}
drivers = entityManager.createQuery(criteriaQuery)
.setFirstResult(page)
.setMaxResults(size)
.getResultList();
}
for (int i = 0; i < drivers.size(); i ) {
otherParamMap.put(drivers.get(i).getId(), countNumOfCars(drivers.get(i).getId()));
}
DataTableResponse<Driver> response = new DataTableResponse<>();
response.setSort(request.getSort());
response.setOrder(request.getOrder());
response.setCurrentPage(request.getCurrentPage());
response.setCurrentSize(request.getPageSize());
response.setItems(drivers);
response.setOtherParamMap(otherParamMap);
return response;
}
private int countNumOfCars(Long id) {
return findById(id).getCars().size();
}
CodePudding user response:
The problem is here:
criteriaQuery.orderBy(criteriaBuilder.desc(from.get(request.getSort())));
// and here
criteriaQuery.orderBy(criteriaBuilder.asc(from.get(request.getSort())));
More specifically this part:
from.get(request.getSort())
Because in the request you are sending the column name as last_name instead of the property name lastName. You have to use the java property names in JPQL and Criteria Queries (which get translated to JPQL), not the native database column names.
