when this line of code
user.status = unitOfWork.getReference(UserStatusEntity::class.java, if(type != UserTypeEnum.Driver) UserStatusEnum.Pending.id else UserStatusEnum.Active.id)
get executed I am getting unnecessary queries!! (unitOfWork.getReference = entityManager.getReference)
first query to get the status by id, even that I am using getReference!!
select use1_0.id, use1_0.title_ar, use1_0.title_en from user_statuses use1_0 where use1_0.id=?
second query I don’t know why it’s geting the user by status id:
select u1_0.status_id, u1_0.id, u1_0.created_at, u1_0.email, u1_0.firebase_token, u1_0.gender_id,
u1_0.is_profile_completed, u1_0.password, u1_0.phone_number, u1_0.type_id, u1_0.updated_at
from auth_users u1_0 where u1_0.status_id=?
if I make it unidirectional relation, it will work as expected no queries at all.
I want to keep the releation bidirectional and not doing this queries.
this is my entities:
@Entity
@Table(
name = "auth_users",
indexes = [
Index(name = "idx_auth_users_phone_number", columnList = "phone_number", unique = true),
Index(name = "idx_auth_users_email", columnList = "email"),
Index(name = "idx_auth_users_type", columnList = "type_id"),
]
)
class AuthUserEntity(
@Column(nullable = false, unique = true)
var phoneNumber: String,
var email: String? = null,
var firebaseToken: String? = null,
) : Auditable2Entity() {
@Id
@Column(columnDefinition = "uuid")
var id: UUID? = null
@Column(nullable = false)
var password: String? = null
@Column(nullable = false)
var isProfileCompleted: Boolean = false
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "status_id", referencedColumnName = "id", nullable = false)
var status: UserStatusEntity? = null
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "type_id", referencedColumnName = "id")
var type: UserTypeEntity? = null
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "gender_id", referencedColumnName = "id")
var gender: GenderEntity? = null
@OneToOne(mappedBy = "user", fetch = FetchType.LAZY, optional = true)
var driver: DriverEntity? = null
@OneToOne(mappedBy = "user", fetch = FetchType.LAZY, optional = true)
var rider: RiderEntity? = null
@OneToOne(mappedBy = "user", fetch = FetchType.LAZY, optional = true)
var partner: PartnerEntity? = null
@OneToMany(mappedBy = "user", cascade = [CascadeType.ALL], orphanRemoval = true)
var roles: MutableSet<UserRoleEntity>? = null
@OneToOne(mappedBy = "user", fetch = FetchType.LAZY, optional = true)
var wallet: WalletEntity? = null
@OneToOne(mappedBy = "referralBy", fetch = FetchType.LAZY, optional = true)
var referralDriver: DriverEntity? = null
@OneToOne(mappedBy = "referralBy", fetch = FetchType.LAZY, optional = true)
var referralRider: RiderEntity? = null
}
@Entity
@Table(name = "user_statuses")
class UserStatusEntity(
) : SharedEntity() {
@Id
var id: Int? = null
@Column(nullable = false)
var titleAr: String? = null
@Column(nullable = false)
var titleEn: String? = null
@OneToMany(mappedBy = "status")
var users: MutableSet<AuthUserEntity>? = null
}
@Component
class UnitOfWork(
val entityManager: EntityManager,
val lookups: LookupRepository, val users: UserRepository,
val partners: PartnerRepository, val drivers: DriverRepository,
val riders: RiderRepository, val categories: CategoryRepository,
val fares: FareRepository, val preferredLocations: PreferredLocationRepository,
val wallets: WalletRepository, val coupons: CouponRepository,
val vehicles: VehicleRepository, val orders: OrderRepository,
val scheduledRides: ScheduledRideRepository, val files: FileRepository,
val documents: DocumentRepository, val otps: OTPRepository
) {
fun <T> getReference(entityClass: Class<T>, primaryKey: Any): T = entityManager.getReference(entityClass, primaryKey)
}
in my build.gradle.kts I enabled bytecode enhancement
hibernate {
enhancement {
enableLazyInitialization.set(true)
enableDirtyTracking.set(true)
enableAssociationManagement.set(true)
}
}