My Entity Structure
import com.application.authserver.core.jpa.entity.AbstractBusinessUnitJpaEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.Filters;
@Entity
@Getter
@Setter
@Table(name = "product_dependent_sub_product", indexes = {
@Index(name = "tenantAndBusinessUnitProductSubProductIndx", columnList = "TENANT,BUSINESS_UNIT_ID,product_id,sub_product_id"),
@Index(name = "tenantAndBusinessUnitProductIndx", columnList = "TENANT,BUSINESS_UNIT_ID,product_id"),
@Index(name = "tenantAndBusinessUnitSubProductIndx", columnList = "TENANT,BUSINESS_UNIT_ID,sub_product_id"),
})
@NoArgsConstructor
@SuperBuilder
@ToString(callSuper = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true)
public class ProductDependentSubProductMappingJpaEntity extends AbstractBusinessUnitJpaEntity implements Auditable {
@Column(name = "product_id")
private Long productId;
@Column(name = "sub_product_id")
private Long subProductId;
@Column(name = "CONSIDER_RISK_SCORE", columnDefinition = "bit(1) default 0")
private Boolean considerRiskScore;
}
AbstractBusinessUnitJpaEntity
import com.application.authserver.constants.CommonConstants;
import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.Filter;
import java.util.Date;
@Getter
@Setter
@ToString(callSuper = true)
//@FilterDef(name = CommonConstants.BUSINESS_UNIT_FILTER, parameters = {@ParamDef(name = "buid", type = Long.class)})
@Filter(name = CommonConstants.BUSINESS_UNIT_FILTER, condition = "BUSINESS_UNIT_ID = :buid")
@MappedSuperclass
@SuppressWarnings("serial")
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
@SuperBuilder
public abstract class AbstractBusinessUnitJpaEntity extends AbstractTenantJpaEntity{
@Column(name = "BUSINESS_UNIT_ID")
@EqualsAndHashCode.Include
private Long businessUnitId;
}
}
AbstractTenantJpaEntity
import java.util.Date;
import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import com.application.authserver.constants.CommonConstants;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
@Getter
@Setter
@ToString(callSuper = true)
@MappedSuperclass
@SuppressWarnings("serial")
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public abstract class AbstractTenantJpaEntity extends AbstractJpaEntity {
@Column(name = "TENANT")
protected Long tenant;
}
AbstractJpaEntity
import java.io.Serializable;
import java.util.Date;
import jakarta.persistence.Column;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
@Getter
@Setter
@ToString
@MappedSuperclass
@AllArgsConstructor
@SuppressWarnings("serial")
@EqualsAndHashCode(of = { "id" })
@NoArgsConstructor
@SuperBuilder
public abstract class AbstractJpaEntity implements Serializable {
@Id
protected Long id;
//other props to keep it clean
//createdAt,updatedAt,createdBy, updatedBy,isPublished,isDeleted
}
Repository:
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.application.authserver.core.jpa.repository.AbstractBusinessUnitJpaRepository;
import com.application.authserver.jpa.entity.ProductDependentSubProductMappingJpaEntity;
@Repository
public interface ProductDependentSubProductMappingJpaRepository extends AbstractBusinessUnitJpaRepository<ProductDependentSubProductMappingJpaEntity, Long> {
List<ProductDependentSubProductMappingJpaEntity> findAllByTenantAndBusinessUnitIdAndProductIdIn(Long tenant,List<Long> productId);
}
AbstractBusinessUnitJpaRepository:
import java.io.Serializable;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.application.authserver.core.jpa.entity.AbstractBusinessUnitJpaEntity;
@NoRepositoryBean
public interface AbstractBusinessUnitJpaRepository<T extends AbstractBusinessUnitJpaEntity,
ID extends Serializable>
extends JpaRepository<T, ID> {
long count();
long countByTenant(Long tenant);
T findByIdAndTenant(ID id,Long tenant);
List<T> findByIdInAndTenant(List<ID> ids,Long tenant);
List<T> findByTenant(Long tenant);
List<T> findByTenant(Long tenant,Sort sort);
Page<T> findByTenant(Long tenant,Pageable pageable);
void flush();
}
problem in this is before migrating to Spring Boot 3 , we were using Spring Boot 2 and hibernate 5 this setup was working, After migrating to Spring Boot 3.2.4 and Hibernate 6.5.0 queries like this : findAllByTenantAndBusinessUnitIdAndProductIdIn where i have reference to super class variable started throwing error like
2024-03-23 11:50:41.395 [03-23 11:50:41 IST] DEBUG [main] mdc:{} NamedQuery.hasNamedQuery:118 - Did not find named query ProductDependentSubProductMappingJpaEntity.findAllByTenantAndBusinessUnitIdAndProductIdIn
2024-03-23 11:50:41.395 [03-23 11:50:41 IST] DEBUG [main] mdc:{} SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke:310 - Creating new EntityManager for shared EntityManager invocation
2024-03-23 11:50:41.395 [03-23 11:50:41 IST] DEBUG [main] mdc:{} NamedQuery.lookupFrom:138 - Looking up named query ProductDependentSubProductMappingJpaEntity.findByTenantAndBusinessUnitIdInAndIsDeleted
2024-03-23 11:50:41.396 [03-23 11:50:41 IST] DEBUG [main] mdc:{} JdbcResourceLocalTransactionCoordinatorImpl.markRollbackOnly:310 - JDBC transaction marked for rollback-only (exception provided for stack trace)
java.lang.Exception: exception just for purpose of providing stack trace
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.markRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:310)
at org.hibernate.internal.AbstractSharedSessionContract.buildNamedQuery(AbstractSharedSessionContract.java:1097)
at org.hibernate.internal.AbstractSharedSessionContract.createNamedQuery(AbstractSharedSessionContract.java:975)
at org.hibernate.internal.AbstractSharedSessionContract.createNamedQuery(AbstractSharedSessionContract.java:136)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:364)
at jdk.proxy2/jdk.proxy2.$Proxy256.createNamedQuery(Unknown Source)
at org.springframework.data.jpa.repository.query.NamedQuery.hasNamedQuery(NamedQuery.java:113)
at org.springframework.data.jpa.repository.query.NamedQuery.lookupFrom(NamedQuery.java:141)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:180)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:252)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:95)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:111)
.....
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:126)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:105)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:499)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:218)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:188)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:618)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343)
tried moving these fields to same class and it is working