Spring Boot (5) JPA : Column name annotation fails (with set naming convention) - spring-boot

I am having an issue where columns are getting renamed to snakecase. Sadly I can not rename the columns since I am creating a 3rd party tool to work on software developed for us by another company. I have googled / searched SO and tried all sorts of fixes. I am a noob at spring / JPA/ hibernate and some help would be greatly appreciated. Using IntelliJ Ultimate if that matters.
Edit:
Might help if I include the error I am getting.
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid column name 'birth_date'.
Entity
package net.glmhc.dmhwebservices.entities;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Type;
import javax.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import org.hibernate.annotations.Cache;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
#Entity
#Table(name = "Clients")
#Cache(usage = CacheConcurrencyStrategy.NONE)
#NamedQueries({#NamedQuery(name = "Client.findById", query = "SELECT c FROM Clients c WHERE c.id = :id")
,#NamedQuery(name = "findGenderById", query = "SELECT c FROM Codes c WHERE c.id = :id")})
public class Clients{
#Id
#Column(columnDefinition = "char(36)")
private String id;
#CreatedBy
#Column(name = "CreateUser", columnDefinition = "char(36)")
private String createUser;
#CreatedDate
#Column(name = "CreateDate")
private LocalDateTime createDate;
#LastModifiedBy
#Column(name = "UpdateUser", columnDefinition = "char(36)")
private String updateUser;
#LastModifiedDate
#Column(name = "UpdateDate")
private LocalDateTime updateDate;
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = false)
private final Set<ClientNames> clientNames = new HashSet<>();
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = false)
private final Set<ClientAddresses> clientAddresses = new HashSet<>();
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = false)
private final Set<ClientEmails> clientEmails = new HashSet<>();
#Column(name = "ClientCode")
private String clientCode;
#Column(name = "AlternateClientCode")
private String alternateClientCode;
#Column(name = "BirthDate")
private LocalDate birthDate;
public Clients(String id, String createUser, LocalDateTime createDate, String updateUser, LocalDateTime updateDate, String clientCode, String alternateClientCode, LocalDate birthDate, boolean declinedEthnicity, boolean declinedLanguage, boolean declinedRace, String mpi, String preferredName, String ssn, Codes genderCodes, String rcopiaId, boolean memoHasHighImportance, String memo, String profileImageId, boolean confidentialClient, String maritalStatus, String stateReportingEthnicity, String veteranStatus, String legalStatus, String employmentStatus, String livingArrangement, String incomeSource, LocalDate livingArrangementLastChanged, Integer grossMonthlyIncome, Integer householdSize, String appUser, Long mendWardId, String genderIdentity, String religiousPreference, String sexualOrientation, String genderAtBirth, String preferredPronouns, String uniqueStateIdentifier) {
this.id = id;
this.createUser = createUser;
this.createDate = createDate;
this.updateUser = updateUser;
this.updateDate = updateDate;
this.clientCode = clientCode;
this.alternateClientCode = alternateClientCode;
this.birthDate = birthDate;
}
public Clients() {
}
#Override
public String toString() {
return "Clients{" +
"id='" + id + '\'' +
", createUser='" + createUser + '\'' +
", createDate=" + createDate +
", updateUser='" + updateUser + '\'' +
", updateDate=" + updateDate +
", clientNames=" + clientNames +
", clientAddresses=" + clientAddresses +
", clientEmails=" + clientEmails +
", clientCode='" + clientCode + '\'' +
", alternateClientCode='" + alternateClientCode + '\'' +
", birthDate=" + birthDate +
'}';
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCreateUser() {
return createUser;
}
public void setCreateUser(String createUser) {
this.createUser = createUser;
}
public LocalDateTime getCreateDate() {
return createDate;
}
public void setCreateDate(LocalDateTime createDate) {
this.createDate = createDate;
}
public String getUpdateUser() {
return updateUser;
}
public void setUpdateUser(String updateUser) {
this.updateUser = updateUser;
}
public LocalDateTime getUpdateDate() {
return updateDate;
}
public void setUpdateDate(LocalDateTime updateDate) {
this.updateDate = updateDate;
}
public Codes getGenderCodes() {
return genderCodes;
}
public void setGenderCodes(Codes genderCodes) {
this.genderCodes = genderCodes;
}
public Set<ClientNames> getClientNames() {
return Collections.unmodifiableSet(clientNames);
}
public Optional<ClientNames> getConfidentialName() {
return clientNames.stream().filter(ClientNames::getConfidentialClient).findFirst();
}
public Optional<ClientNames> getNonAliasName() {
return clientNames.stream().filter(clientNames -> !clientNames.getAlias()).findFirst();
}
public Set<ClientAddresses> getClientAddresses() {return Collections.unmodifiableSet(clientAddresses);}
public Set<ClientEmails> getClientEmails() { return Collections.unmodifiableSet(clientEmails); }
public String getClientCode() {
return clientCode;
}
public void setClientCode(String clientCode) {
this.clientCode = clientCode;
}
public String getAlternateClientCode() {
return alternateClientCode;
}
public void setAlternateClientCode(String alternateClientCode) {
this.alternateClientCode = alternateClientCode;
}
public LocalDate getBirthDate() {
return birthDate;
}
public void setBirthDate(LocalDate birthDate) {
this.birthDate = birthDate;
}
}
}
application.yml
spring:
jpa:
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
hibernate:
dialect: org.hibernate.dialect.SQLServer2008Dialect
properties:
datasource:
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://localhost:1433/;databaseName:DBNAME
username: sa
password:

You have configured the physical naming strategy to use org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl which by implementation should return the Identifier name as set ( which is what you want).
Maybe you also have to configure the implicit naming strategy for the case you have some fields where you didn't set the column name explicitely.
Your application.yml file could look like this (i removed the properties field from it since you didn't used it):
spring:
jpa:
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
hibernate:
dialect: org.hibernate.dialect.SQLServer2008Dialect
datasource:
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://localhost:1433/;databaseName:DBNAME
username: sa
password:
If none of the strategies works for you, you can always write your own by implementing the interfaces org.hibernate.boot.model.naming.PhysicalNamingStrategy (for physical naming) and org.hibernate.boot.model.naming.ImplicitNamingStrategy (for implicit naming).

Turns out the context of my application was being bypassed as I was not using all of spring boot and partially creating my own context. Rebuilding the context to work more in line with spring boot made it pick up the proper configuration from applicatiom.yml.

Related

Issue with Join Fetch Hibernate query

I am new using hibernate join fetch queries and would like some help on the below matter.
I have one Entity that has quite a few OneToMany associations. And in the rest call
I need to load all of those associations to prepare the result.
I was using Jpa findAll(Pageable) method however on production seeing huge load on read queries. I understand that I ran into N+1 problem which I am trying to solve however getting bellow error:
{
"title" : "Internal Server Error",
"status" : 500,
"detail" : "firstResult/maxResults specified with collection fetch. In memory pagination was about to be applied. Failing because 'Fail on pagination over collection fetch' is enabled.; nested exception is org.hibernate.HibernateException: firstResult/maxResults specified with collection fetch. In memory pagination was about to be applied. Failing because 'Fail on pagination over collection fetch' is enabled.",
"cause" : {
"title" : "Internal Server Error",
"status" : 500,
"detail" : "firstResult/maxResults specified with collection fetch. In memory pagination was about to be applied. Failing because 'Fail on pagination over collection fetch' is enabled."
}
}
====================
using Running with Spring Boot v2.5.4, Spring v5.3.9 and mysql 5.7
Here is my code snippet:
Entity:
package com.pitstop.catalogue.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.pitstop.catalogue.util.EligibleOffer;
import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.time.Instant;
import java.util.*;
/**
* A Product.
*/
#Entity
#Table(name = "product")
#org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
public static final String PRODUCT_NAME = "name";
public static final String PRODUCT_CATEGORY = "category_id";
public static final String PRODUCT_UNIT_PRICE = "unit_price";
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Size(max = 250)
#Column(name = PRODUCT_NAME, length = 50, nullable = false)
private String name;
#Size(max = 1000)
#Column(name = "description", length = 200)
private String description;
private Long brandId;
#Size(max = 500)
#Column(name = "product_icon_url", length = 500)
private String productIconUrl;
#Column(name = PRODUCT_UNIT_PRICE)
private Double unitPrice;
#Column(name = "gst_rate")
private Double gstRate;
#Size(max = 45)
#Column(name = "part_no", length = 45)
private String partNo;
#Size(max = 45)
#Column(name = "serial_no", length = 45)
private String serialNo;
#Size(max = 45)
#Column(name = "unit_type", length = 45)
private String unitType;
#Column(name = "line_item_id")
private Long lineItemId;
private Long categoryId;
#OneToMany(mappedBy = "product", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#Fetch(FetchMode.JOIN)
#JsonIgnoreProperties(value = {"product"}, allowSetters = true)
#BatchSize(size = 20)
#org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
private Set<Offer> offers = new HashSet<>();
#OneToMany(mappedBy = "product", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#Fetch(FetchMode.JOIN)
#JsonIgnoreProperties(value = {"product"}, allowSetters = true)
#BatchSize(size = 20)
#org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
private Set<ProductAttributes> productAttributes = new HashSet<>();
#OneToMany(mappedBy = "product", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#Fetch(FetchMode.JOIN)
#JsonIgnoreProperties(value = {"product", "productModel"}, allowSetters = true)
#BatchSize(size = 20)
#org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
private Set<ProductModelMapping> productModelMappings = new HashSet<>();
#OneToMany(mappedBy = "product", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#Fetch(FetchMode.JOIN)
#JsonIgnoreProperties(value = {"product"}, allowSetters = true)
#BatchSize(size = 20)
#org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
private Set<ProductSeller> productSellers = new HashSet<>();
#Size(max = 45)
#Column(name = "tag", length = 50)
private String tag;
#Column(name = "created")
private Instant created;
#Column(name = "created_by", length = 100)
private String createdBy;
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 getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getProductIconUrl() {
return productIconUrl;
}
public void setProductIconUrl(String productIconUrl) {
this.productIconUrl = productIconUrl;
}
public Double getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(Double unitPrice) {
this.unitPrice = unitPrice;
}
public Double getGstRate() {
return gstRate;
}
public void setGstRate(Double gstRate) {
this.gstRate = gstRate;
}
public String getPartNo() {
return partNo;
}
public void setPartNo(String partNo) {
this.partNo = partNo;
}
public String getSerialNo() {
return serialNo;
}
public void setSerialNo(String serialNo) {
this.serialNo = serialNo;
}
public String getUnitType() {
return unitType;
}
public void setUnitType(String unitType) {
this.unitType = unitType;
}
public Set<Offer> getOffers() {
return offers;
}
public void setOffers(Set<Offer> offers) {
this.offers = offers;
}
public Set<ProductAttributes> getProductAttributes() {
return productAttributes;
}
public void setProductAttributes(Set<ProductAttributes> productAttributes) {
this.productAttributes = productAttributes;
}
public Set<ProductModelMapping> getProductModelMappings() {
return productModelMappings;
}
public void setProductModelMappings(Set<ProductModelMapping> productModelMappings) {
this.productModelMappings = productModelMappings;
}
public Set<ProductSeller> getProductSellers() {
return productSellers;
}
public void setProductSellers(Set<ProductSeller> productSellers) {
this.productSellers = productSellers;
}
public Long getLineItemId() {
return lineItemId;
}
public void setLineItemId(Long lineItemId) {
this.lineItemId = lineItemId;
}
#Transient
public double getSellingPrice() {
// As discussed with Rohit, iterate over all the valid offers (by date)
// and then apply which has the highest discount value. This is for Pitstop offers only.
// Sellers offers will be created by sellers.
if (this.offers.size() > 0) {
Double sellingPriceFromOffers = EligibleOffer.apply(this.offers, this.unitPrice);
return sellingPriceFromOffers;
}
return this.unitPrice;
}
#Transient
public double getProductUnitPrice() {
return this.unitPrice;
}
#Transient
public double getProductGstRate() {
if (callSellers() != null && callSellers().size() > 0) {
ProductSeller productSeller = callSellers().get(0);
return productSeller.getGstRate();
}
return gstRate;
}
#Transient
public List<ProductSeller> callSellers() {
//sorting products by seller price in ascending order
List<ProductSeller> sellers = new ArrayList<>();
sellers.addAll(productSellers);
Collections.sort(sellers, (Comparator.comparing(ProductSeller::getUnitPrice)));
return sellers;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public Instant getCreated() {
return created;
}
public void setCreated(Instant created) {
this.created = created;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Long getBrandId() {
return brandId;
}
public void setBrandId(Long brandId) {
this.brandId = brandId;
}
public Long getCategoryId() {
return categoryId;
}
public void setCategoryId(Long categoryId) {
this.categoryId = categoryId;
}
#Override
public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
", description='" + description + '\'' +
", brand=" + brandId +
", productIconUrl='" + productIconUrl + '\'' +
", unitPrice=" + unitPrice +
", gstRate=" + gstRate +
", partNo='" + partNo + '\'' +
", serialNo='" + serialNo + '\'' +
", unitType='" + unitType + '\'' +
", lineItemId=" + lineItemId +
", category=" + categoryId +
", offers=" + offers +
", productAttributes=" + productAttributes +
", productModelMappings=" + productModelMappings +
", productSellers=" + productSellers +
", tag='" + tag + '\'' +
", created=" + created +
", createdBy='" + createdBy + '\'' +
'}';
}
}
Repository:
#Repository
public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {
List<Product> findAllByCategoryId(Long categoryId);
List<Product> findAllByBrandId(Long brandId);
#Query(value = "select p " +
"from Product p " +
"left join fetch p.productAttributes productAttributes",
countQuery = "select count(p) from Product p")
Page<Product> findAll(Pageable pageable);
}

Spring Boot Hibernate one to many. Lazy many not written to database

I have two entities. Person (one) and Contactdetails (many).
Contactdetails are lazy loading. I have no problem with creating a new Person and get it written into the database. For my test I use the MySQL database installed locally filled up with dummy data. I run kind of integration test.
In my test code I use #Transactional annotation in order to stay inside one session where I fetch a Person, create a new Contacdetails, connect them together and then save the Person, which will cascade save the Contactdetails too. In theory...
Contactdetails is not written to the database. Interestingly, if I write to console all Contactdetails inside the #Transactional annotated test method, I see the new Contactdetails created. As soon es I leave this test method, this freshly created Contactdetails is no more visible.
My Entities are as follows:
Person:
package com.szivalaszlo.contracts.landon.data.entity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.time.LocalDate;
import java.util.Objects;
#Entity
#Table(name="person")
public class Person {
private static Logger logger = LogManager.getLogger();
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "date_of_birth")
private LocalDate dateOfBirth;
#Column(name = "first_name_mother")
private String firstNameMother;
#Column(name = "last_name_mother")
private String lastNameMother;
#OneToMany(fetch=FetchType.LAZY, mappedBy = "person", cascade = CascadeType.ALL) // refers to person attribute of Contactdetails class
private List<Contactdetails> contactdetails;
#ManyToMany(fetch=FetchType.LAZY)
#JoinTable(name = "buyer_contract",
joinColumns = #JoinColumn(name = "person_buyerid"),
inverseJoinColumns = #JoinColumn(name = "contractid"))
List<Contract> buyerContracts;
#ManyToMany(fetch=FetchType.LAZY)
#JoinTable(name = "seller_contract",
joinColumns = #JoinColumn(name = "person_sellerid"),
inverseJoinColumns = #JoinColumn(name = "contractid"))
List<Contract> sellerContracts;
public Person(){
}
public Person(String firstName, String lastName, String dateOfBirth, String firstNameMother, String lastNameMother) {
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = LocalDate.parse(dateOfBirth);
this.firstNameMother = firstNameMother;
this.lastNameMother = lastNameMother;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 LocalDate getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getFirstNameMother() {
return firstNameMother;
}
public void setFirstNameMother(String firstNameMother) {
this.firstNameMother = firstNameMother;
}
public String getLastNameMother() {
return lastNameMother;
}
public void setLastNameMother(String lastNameMother) {
this.lastNameMother = lastNameMother;
}
public List<Contactdetails> getContactdetails() {
return contactdetails;
}
public void addContactdetail(Contactdetails contactdetail){
if(null == contactdetails){
contactdetails = new ArrayList<Contactdetails>();
}
contactdetails.add(contactdetail);
}
public String getStringForEqualsCheck(){
return firstName+lastName+dateOfBirth.toString()+firstNameMother+lastNameMother;
}
#Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof Person))
return false;
if (obj == this)
return true;
return this.getStringForEqualsCheck().equals(((Person) obj).getStringForEqualsCheck());
}
#Override
public int hashCode() {
return Objects.hash(firstName, lastName, dateOfBirth, firstNameMother, lastNameMother);
}
#Override
public String toString() {
return "Person{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", dateOfBirth=" + dateOfBirth +
", firstNameMother='" + firstNameMother + '\'' +
", lastNameMother='" + lastNameMother + '\'' +
'}';
}
}
Contactdetails:
package com.szivalaszlo.contracts.landon.data.entity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Table(name="contactdetails")
public class Contactdetails {
private static Logger logger = LogManager.getLogger();
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "address")
private String address;
#Column(name = "email")
private String email;
#Column(name = "phone")
private String phone;
#ManyToOne
#JoinColumn(name = "personid", nullable = false)
private Person person;
public Contactdetails(){
}
public Contactdetails(String address, String email, String phone) {
this.address = address;
this.email = email;
this.phone = phone;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
logger.debug("Person is set for contactdetail: " + this.toString() + " person: " + this.person.toString());
}
public String getStringForEqualsCheck(){
return address+email+phone;
}
#Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof Contactdetails))
return false;
if (obj == this)
return true;
return this.getStringForEqualsCheck().equals(((Contactdetails) obj).getStringForEqualsCheck());
}
#Override
public int hashCode() {
return Objects.hash(address, email, phone);
}
#Override
public String toString() {
return "Contactdetails{" +
"id=" + id +
", address='" + address + '\'' +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
", person=" + person +
'}';
}
}
Service class:
package com.szivalaszlo.contracts.landon.business.domain;
import com.szivalaszlo.contracts.landon.data.entity.Contactdetails;
import com.szivalaszlo.contracts.landon.data.entity.Person;
import com.szivalaszlo.contracts.landon.data.repository.ContactdetailsRepository;
import com.szivalaszlo.contracts.landon.data.repository.PersonRepository;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
#Service
public class PersonService {
private static Logger logger = LogManager.getLogger();
private PersonRepository personRepository;
private ContactdetailsRepository contactdetailsRepository;
#Autowired
public PersonService(PersonRepository personRepository, ContactdetailsRepository contactdetailsRepository){
this.personRepository = personRepository;
this.contactdetailsRepository = contactdetailsRepository;
}
public int createPerson(String firstName, String lastName, String dateOfBirth, String firstNameMother, String lastNameMother){
Person person = new Person(firstName, lastName, dateOfBirth, firstNameMother, lastNameMother);
if(personAlreadyExistsInDb(person)){
logger.debug("Same person already found in Db. Person: " + person.toString());
return -1;
}else{
personRepository.save(person);
return person.getId();
}
}
private boolean personAlreadyExistsInDb(Person person){
HashSet<Person> allPersonFromDb = personRepository.findAll();
if (allPersonFromDb.contains(person)){
return true;
}else{
return false;
}
}
public void createContactdetailsForPerson(Person person, String address, String email, String phone){
Contactdetails contactdetails = new Contactdetails(address, email, phone);
if(contactdetailsAlreadyExistForPerson(contactdetails, person)){
logger.debug("Same contactdetail for person already found " + person.toString() + " " + contactdetails.toString());
} else{
contactdetails.setPerson(person);
person.addContactdetail(contactdetails);
contactdetailsRepository.save(contactdetails);
personRepository.save(person);
}
}
private boolean contactdetailsAlreadyExistForPerson(Contactdetails contactdetails, Person person){
List<Contactdetails> allContactdetailsForPersonFromDb = person.getContactdetails();
if(null == allContactdetailsForPersonFromDb || allContactdetailsForPersonFromDb.size() == 0){
return false;
}
if(!allContactdetailsForPersonFromDb.contains(contactdetails)){
return false;
}
return true;
}
}
Test class:
package com.szivalaszlo.contracts;
import com.szivalaszlo.contracts.landon.business.domain.PersonService;
import com.szivalaszlo.contracts.landon.data.entity.Contactdetails;
import com.szivalaszlo.contracts.landon.data.entity.Person;
import com.szivalaszlo.contracts.landon.data.repository.ContactdetailsRepository;
import com.szivalaszlo.contracts.landon.data.repository.PersonRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Random;
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PersonServiceTest_ {
private static Logger logger = LogManager.getLogger();
#Autowired
private PersonRepository personRepository;
#Autowired
private ContactdetailsRepository contactdetailsRepository;
Random rand = new Random();
int randomNumber = rand.nextInt(899)+100;
private String address = "test address street 1 in City "+randomNumber;
private String email = "testemail#exmaple.com " +randomNumber;
private String phone = "+41 12 345 78 90 " +randomNumber;
#Test
#Transactional(propagation = Propagation.REQUIRED)
public void it_should_save_contactdetail_to_person(){
PersonService testPersonService = new PersonService(personRepository, contactdetailsRepository);
Person testPerson = personRepository.findById(179); //I have an id# 179 Person in the database fully detailed.
testPersonService.createContactdetailsForPerson(testPerson, address, email, phone);
List<Contactdetails> allStoredContactdetailsinDB = contactdetailsRepository.findAll();
allStoredContactdetailsinDB.forEach(item->System.out.println(item));
}
}
The test runs with no error. I see the following output in the console:
Bradlystad, ND 98886-5789', email='maverick85#example.com', phone='464-812-3618', person=Person{id=98, firstName='Eldridge', lastName='Reichel', dateOfBirth=1981-08-07, firstNameMother='Brianne', lastNameMother='Ryan'}}
Contactdetails{id=99, address='569 Langosh Turnpike Suite 235
East Archibald, FL 43208-3081', email='spouros#example.org', phone='08976297815', person=Person{id=99, firstName='Myrtie', lastName='Graham', dateOfBirth=1982-01-19, firstNameMother='Libby', lastNameMother='Veum'}}
Contactdetails{id=100, address='010 Pfeffer Islands
Kiehnside, FL 25044-1157', email='paucek.grover#example.com', phone='1-157-850-0688x390', person=Person{id=100, firstName='Katheryn', lastName='Hoppe', dateOfBirth=2009-06-22, firstNameMother='Virginie', lastNameMother='Donnelly'}}
Contactdetails{id=106, address='test address street 1 in City 623', email='testemail#exmaple.com 623', phone='+41 12 345 78 90 623', person=Person{id=179, firstName='TestJhonFirst808', lastName='TestSmithLast808', dateOfBirth=1990-11-11, firstNameMother='TestJackieMotherFirst808', lastNameMother='TestSmithMotherLast808'}}
The interesting part is the last line which shows, that the Contactdetails is created in the db with id#106.
When I query the database after the test is run, I don't see the new line in the table.
By default, test transactions will be automatically rolled back after
completion of the test; however, transactional commit and rollback
behavior can be configured declaratively via the #Commit and #Rollback
annotations
Add the following annotation to your test:
#Rollback(false)

Getting ConstraintViolationException while saving a row with embedded key in the table with many-to-many mapping between two entities using Spring JPA

In our spring boot Restful WebService, we have two master tables with many-to-many relationship between them. But in the transaction table, we want one extra field (current_time) as part of the embedded key other than the primary keys of the two tables. Now, we’ve created a separate class for defining embedded primary key using #Embeddable. Now, while inserting one transaction row to transaction table using Spring JPA, I am manually setting the primary keys in the corresponding entity and calling the save method on corresponding repository. But It is giving me ConstraintViolationException as the current_time is going with null value even if I have manually set it. Any help would be highly appreciated.
First Entity is as follows :
#Entity
#Table(name = "project")
public class Project {
#Id
#GenericGenerator(name = "projectid", strategy = "com.sample.upload.entity.ProjectIDGenerator")
#GeneratedValue(generator = "projectid")
#Column(name = "projectid")
private String projectID;
#Column(name = "project_name")
private String projectName;
#Column(name = "project_descr")
private String projectDesc;
#Column(name = "project_input_path")
private String projectPath;
#Column(name = "project_creation_time")
private Calendar projectCreationTime;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "project_migration", joinColumns = #JoinColumn(name = "projectid", referencedColumnName = "projectid"), inverseJoinColumns = #JoinColumn(name = "migratorid", referencedColumnName = "migratorid"))
private List<Migrator> migrators;
#Column(name = "account_name")
private String accountName;
#Column(name = "account_group")
private String accountGroup;
public String getProjectID() {
return projectID;
}
public void setProjectID(String projectID) {
this.projectID = projectID;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getAccountGroup() {
return accountGroup;
}
public void setAccountGroup(String accountGroup) {
this.accountGroup = accountGroup;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getProjectDesc() {
return projectDesc;
}
public void setProjectDesc(String projectDesc) {
this.projectDesc = projectDesc;
}
public String getProjectPath() {
return projectPath;
}
public void setProjectPath(String projectPath) {
this.projectPath = projectPath;
}
public Calendar getProjectCreationTime() {
return projectCreationTime;
}
public void setProjectCreationTime(Calendar projectCreationTime) {
this.projectCreationTime = projectCreationTime;
}
public List<Migrator> getMigrators() {
return migrators;
}
public void setMigrators(List<Migrator> migrators) {
this.migrators = migrators;
}
}
Second Entity :
#Entity
#GenericGenerator(name = "generatorName", strategy = "increment")
#Table(name = "migrator")
public class Migrator {
#Id
#GeneratedValue(generator = "generatorName")
#Column(name = "migratorid")
private String migratorId;
#Column(name = "src_tech_name")
private String srcTechName;
#Column(name = "dest_tech_name")
private String destTechName;
#Column(name = "migrator_name")
private String migratorName;
#Column(name = "migrator_type")
private String migratorType;
public String getMigratorId() {
return migratorId;
}
public void setMigratorId(String migratorId) {
this.migratorId = migratorId;
}
public String getSrcTechName() {
return srcTechName;
}
public void setSrcTechName(String srcTechName) {
this.srcTechName = srcTechName;
}
public String getDestTechName() {
return destTechName;
}
public void setDestTechName(String destTechName) {
this.destTechName = destTechName;
}
public String getMigratorName() {
return migratorName;
}
public void setMigratorName(String migratorName) {
this.migratorName = migratorName;
}
public String getMigratorType() {
return migratorType;
}
public void setMigratorType(String migratorType) {
this.migratorType = migratorType;
}
#Override
public String toString() {
return "Technology [migratorId=" + migratorId + ", srcTechName=" + srcTechName + ", destTechName="
+ destTechName + ", migratorName=" + migratorName + ", migratorType=" + migratorType + "]";
}
}
The join (transaction) table's entity :
#Entity
#Table(name = "project_migration")
public class ProjectMigration {
#EmbeddedId
private ProjectMigrationID migrationId;
#Column(name ="migration_finish_time")
private Calendar migrationFinishTime;
#Column(name ="time_in_millis_for_migration")
private long timeInMillisForMigration;
#Column(name ="migration_status")
private String migrationStatus;
#Column(name ="migrated_codebase_path")
private String migratedCodeBasePath;
The embedded Primary Key class is as follows:
#Embeddable
public class ProjectMigrationID implements Serializable {
private static final long serialVersionUID = -3623993529011381924L;
#Column(name = "projectid")
private String projectId;
#Column(name = "migratorid")
private String migratorId;
#Column(name = "migration_start_time")
private Calendar migrationStartTime;
public ProjectMigrationID() {
}
public ProjectMigrationID(String projectId, String migratorId, Calendar migrationStartTime) {
this.projectId = projectId;
this.migratorId = migratorId;
this.migrationStartTime = migrationStartTime;
}
The snippet from service Class :
for (String migratorId : data.getMigratorIds()) {
Migrator migrator = migratorRepository.findByMigratorId(migratorId);
migrators.add(migrator);
}
if (projectId != null) {
project = projectRepository.findByProjectID(projectId);
System.out.println(project==null);
project.setMigrators(migrators);
System.out.println("I am here");
if (project != null) {
//project.setMigrationStatus("In Progress");
ProjectMigrationID pmId = new ProjectMigrationID();
pmId.setProjectId(project.getProjectID());
pmId.setMigratorId(project.getMigrators().get(0).getMigratorId());
pmId.setMigrationStartTime(new GregorianCalendar());
ProjectMigration pm = new ProjectMigration();
pm.setMigrationId(pmId);
pm.setMigrationStatus("Pending");
projectMigrationRepository.save(pm);
That's because of the #JoinTable where the date is not included and it skips the insertion. If you include a column with all the primary keys needed, it will work as expected.
Only the columns mapped via #JoinTable will be included during insertion or update (defaults to true when mapped)
Either include the date time column in the Project class or use association without #JoinTable.
I'm editing via mobile. So please ignore typos if any.

How to retrieve data from a one to one mapped entity after a filter is applied on to the mapped entity's attribute spring

How to retrieve data from a one to one mapped entity after a filter is applied on to the mapped entity's attribute.
This is my Hotel Entity Class..
package com.springmvcweb.model;
import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
#Entity
#Table(name = "HOTEL", schema = "HOTEL")
public class HotelEntity implements Serializable{
private long hotelId;
private String hotelName;
private String hotelDescription;
private String hotelWebsite;
private Long hotelPhoneNo;
private String hotelEmail;
private Long hotelStarRating;
private AddressEntity addressEntity;
private CategoryEntity categoryEntity;
private List<AmenityEntity> amenitiesList;
#ManyToMany(cascade = {CascadeType.MERGE,CascadeType.PERSIST,CascadeType.DETACH,CascadeType.REFRESH})
#JoinTable(name = "HOTEL_AMENITY", joinColumns = {#JoinColumn(name = "HOTEL_ID", referencedColumnName = "HOTEL_ID")},
inverseJoinColumns = {#JoinColumn(name = "AMENITY_ID", referencedColumnName = "AMENITY_ID")})
public List<AmenityEntity> getAmenitiesList() {
return amenitiesList;
}
public void setAmenitiesList(List<AmenityEntity> amenitiesList) {
this.amenitiesList = amenitiesList;
}
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "HOTEL_ADDRESS_ID")
public AddressEntity getAddressEntity() {
return addressEntity;
}
public void setAddressEntity(AddressEntity addressEntity) {
this.addressEntity = addressEntity;
}
#ManyToOne(cascade = {CascadeType.MERGE,CascadeType.PERSIST,CascadeType.DETACH,CascadeType.REFRESH})
#JoinColumn(name = "HOTEL_CATEGORY_ID")
public CategoryEntity getCategoryEntity() {
return categoryEntity;
}
public void setCategoryEntity(CategoryEntity categoryEntity) {
this.categoryEntity = categoryEntity;
}
#Id
#Column(name = "HOTEL_ID")
public long getHotelId() {
return hotelId;
}
public void setHotelId(long hotelId) {
this.hotelId = hotelId;
}
#Basic
#Column(name = "HOTEL_NAME")
public String getHotelName() {
return hotelName;
}
public void setHotelName(String hotelName) {
this.hotelName = hotelName;
}
#Basic
#Column(name = "HOTEL_DESCRIPTION")
public String getHotelDescription() {
return hotelDescription;
}
public void setHotelDescription(String hotelDescription) {
this.hotelDescription = hotelDescription;
}
#Basic
#Column(name = "HOTEL_WEBSITE")
public String getHotelWebsite() {
return hotelWebsite;
}
public void setHotelWebsite(String hotelWebsite) {
this.hotelWebsite = hotelWebsite;
}
#Basic
#Column(name = "HOTEL_PHONE_NO")
public Long getHotelPhoneNo() {
return hotelPhoneNo;
}
public void setHotelPhoneNo(Long hotelPhoneNo) {
this.hotelPhoneNo = hotelPhoneNo;
}
#Basic
#Column(name = "HOTEL_EMAIL")
public String getHotelEmail() {
return hotelEmail;
}
public void setHotelEmail(String hotelEmail) {
this.hotelEmail = hotelEmail;
}
#Basic
#Column(name = "HOTEL_STAR_RATING")
public Long getHotelStarRating() {
return hotelStarRating;
}
public void setHotelStarRating(Long hotelStarRating) {
this.hotelStarRating = hotelStarRating;
}
public void addAmenities(AmenityEntity amenityEntity){
if(amenitiesList==null){
amenitiesList = new ArrayList<>();
}
amenitiesList.add(amenityEntity);
}
#Override
public String toString() {
return "HotelEntity{" +
"hotelId=" + hotelId +
", hotelName='" + hotelName + '\'' +
", hotelDescription='" + hotelDescription + '\'' +
", hotelWebsite='" + hotelWebsite + '\'' +
", hotelPhoneNo=" + hotelPhoneNo +
", hotelEmail='" + hotelEmail + '\'' +
", hotelStarRating=" + hotelStarRating +
", addressEntity=" + addressEntity +
", categoryEntity=" + categoryEntity +
", amenitiesList=" + amenitiesList +
'}';
}
}
This is AddressEntity Class:
package com.springmvcweb.model;
import javax.persistence.*;
import java.io.Serializable;
#Entity
#Table(name = "ADDRESS", schema = "HOTEL")
public class AddressEntity implements Serializable {
private long addressId;
private String addressLine1;
private String addressLine2;
private String cityName;
private String stateName;
private String countryName;
private Long pincode;
#Id
#Column(name = "ADDRESS_ID")
public long getAddressId() {
return addressId;
}
public void setAddressId(long addressId) {
this.addressId = addressId;
}
#Basic
#Column(name = "ADDRESS_LINE1")
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
#Basic
#Column(name = "ADDRESS_LINE2")
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
#Basic
#Column(name = "CITY_NAME")
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
#Basic
#Column(name = "STATE_NAME")
public String getStateName() {
return stateName;
}
public void setStateName(String stateName) {
this.stateName = stateName;
}
#Basic
#Column(name = "COUNTRY_NAME")
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
#Basic
#Column(name = "PINCODE")
public Long getPincode() {
return pincode;
}
public void setPincode(Long pincode) {
this.pincode = pincode;
}
}
Now I want to retrieve all those hotels filtered by their location(say cityname or statename) and I'm using query like this:
#Override
public List<HotelEntity> getHotelsByLocation(String location) {
try{
session = sessionFactory.getCurrentSession();
}catch (Exception e){
session = sessionFactory.openSession();
}
Query query = session.createQuery("from HotelEntity where HotelEntity.addressEntity.cityName " +
"like :location");
query.setParameter("location",location);
return query.getResultList();
}
Also I've used FetchType as EAGER in the HotelEntity OneToOne Mapping like this:
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "HOTEL_ADDRESS_ID")
public AddressEntity getAddressEntity() {
return addressEntity;
}
Right now it is giving me a null pointer exception. Please guide.
#OneToOne relationship is eagerly fetched anyway so adding that information is redundant.
Regarding the query I would form it like the following:
" select he from HotelEntity he
" inner join he.addressEntity ae"
" where ae.cityName like :location");

Spring Hibernate lazy load behavior

I am making a web based app in spring/hibernate. In database I am using onetomany and manytoone relations. I have manytoone relationship in users for location and onetomany relationship for users in location. In both entities I have lazy loading option turned on. As per my understanding if this is turned on, the database query to get the location should not be executed until explicitly called for it but whenever I do a get from the userdao the below query is executed which makes me think that even after having the lazy option turned on it is retrieving the location information. Can anyone let me know what am I doing wrong or is this the expected behavior.
Below is my user entity code
package com.kwisque.database.model;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;
#Entity
#Table(name = "USERS")
public class User implements Serializable{
#Id
#Column(name = "USER_ID", unique = true, nullable = false)
private String userId;
#Column(name = "NAME", nullable = true, length = 32)
private String name;
#Column(name = "PASSWORD", nullable = false, length = 64)
private String password;
#Column(name = "EMAIL_ID", nullable = true, length = 128)
private String emailId;
#Column(name = "ACTIVE", nullable = false, length = 1)
private Integer active;
#Column(name = "PROVIDER", nullable = false, length = 32)
private String provider;
#ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
#JoinTable(
name = "USER_ROLE",
joinColumns = #JoinColumn(name = "USER_ID"),
inverseJoinColumns = #JoinColumn(name = "ROLE_ID")
)
private Set<Role> roles = new HashSet<>();
//#ManyToOne(fetch = FetchType.LAZY)
//#JoinColumn(name = "LOCATION_ID", nullable = true)
#ManyToOne(fetch=FetchType.LAZY, cascade={javax.persistence.CascadeType.ALL})
#JoinTable(name="USER_LOCATION_INFO",
joinColumns={#javax.persistence.JoinColumn(name="USER_ID")},
inverseJoinColumns={#javax.persistence.JoinColumn(name="LOCATION_ID")})
private Location location;
// #OneToMany(fetch = FetchType.LAZY)
// #JoinColumn(name = "SPECIALIZATION_ID", nullable = true)
#OneToMany(fetch=FetchType.LAZY, cascade={javax.persistence.CascadeType.ALL})
#JoinTable(name="USER_SPECIALIZATION_INFO",
joinColumns={#javax.persistence.JoinColumn(name="USER_ID")},
inverseJoinColumns={#javax.persistence.JoinColumn(name="SPECIALIZATION_ID")})
private Set<Specialization> specialization = new HashSet<>();
public User() {
}
public User(final String userId, final String name, final String password, final String emailId, final Integer active, final String provider, final Set<Role> roles, final Location location) {
this.userId = userId;
this.name = name;
this.password = password;
this.emailId = emailId;
this.active = active;
this.provider = provider;
this.roles = roles;
this.location = location;
}
public String getUserId() {
return userId;
}
public void setUserId(final String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(final String password) {
this.password = password;
}
public Integer getActive() {
return active;
}
public void setActive(final Integer active) {
this.active = active;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(final Set<Role> roles) {
this.roles = roles;
}
public String getProvider() {
return provider;
}
public void setProvider(final String provider) {
this.provider = provider;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(final String emailId) {
this.emailId = emailId;
}
public Location getLocation() {
return location;
}
public void setLocation(final Location location) {
this.location = location;
}
}
Location entity code
package com.kwisque.database.model;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
#Table(name = "LOCATION")
public class Location implements Serializable {
private static final long serialVersionUID = -7153748534015057865L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "LOCATION_ID", unique = true, nullable = false)
private Integer locationId;
#Column(name = "ZIP_CODE", nullable = true, length = 132)
private String zipCode;
#Column(name = "STATE_ABBR", nullable = true, length = 132)
private String stateAbbr;
#Column(name = "LATITUDE", nullable = true, length = 132)
private double latitude;
#Column(name = "LONGITUDE", nullable = true, length = 132)
private double longitude;
#Column(name = "CITY", nullable = true, length = 132)
private String city;
#Column(name = "STATE", nullable = true, length = 132)
private String state;
#JsonIgnore
#OneToMany(fetch = FetchType.LAZY, mappedBy = "location")
private Set<User> users;
public double getLatitude() {
return this.latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return this.longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public Location() {
}
public Location(Integer locationId, long longitude, String city, long latitude, String zipCode, String state,
String stateAbbr, Set<User> users) {
this.locationId = locationId;
this.longitude = longitude;
this.latitude = latitude;
this.city = city;
this.state = state;
this.stateAbbr = stateAbbr;
this.users = users;
}
public Integer getLocationId() {
return this.locationId;
}
public void setLocationId(Integer locationId) {
this.locationId = locationId;
}
#JsonIgnore
public Set<User> getUser() {
return this.users;
}
#JsonIgnore
public void setUser(Set<User> users) {
this.users = users;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public String getZipCode() {
return this.zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getStateAbbr() {
return this.stateAbbr;
}
public void setStateAbbr(String stateAbbr) {
this.stateAbbr = stateAbbr;
}
}
Query being executed at my get from USerDao
Hibernate: select user0_.USER_ID as USER_ID1_3_0_, user0_.ACTIVE as ACTIVE2_3_0_, user0_.EMAIL_ID as EMAIL_ID3_3_0_, user0_.NAME as NAME4_3_0_, user0_.PASSWORD as PASSWORD5_3_0_, user0_.PROVIDER as PROVIDER6_3_0_, user0_1_.LOCATION_ID as LOCATION1_4_0_, roles1_.USER_ID as USER_ID1_3_1_, role2_.ROLE_ID as ROLE_ID2_5_1_, role2_.ROLE_ID as ROLE_ID1_1_2_, role2_.NAME as NAME2_1_2_ from USERS user0_ left outer join USER_LOCATION_INFO user0_1_ on user0_.USER_ID=user0_1_.USER_ID left outer join USER_ROLE roles1_ on user0_.USER_ID=roles1_.USER_ID left outer join ROLE role2_ on roles1_.ROLE_ID=role2_.ROLE_ID where user0_.USER_ID=?

Resources