I am using queryDSL to fetch the inner collection of data and failed to do so. My entities are
#Entity
#Table(name = "countries")
#Setter
#Getter
public class Country {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long countryId;
#Column(name = "name")
private String name;
#Column(name = "data")
private String data;
#OneToOne(mappedBy = "country")
private State stateJoin;
}
#Entity
#Table(name = "states")
#Setter
#Getter
public class State {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long stateId;
#Column(name = "name")
private String name;
#Column(name = "count")
private String count;
#Column(name = "co_id")
private Long countryId;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "co_id", referencedColumnName = "id", updatable = false, insertable = false)
private Country country;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "state_id", referencedColumnName = "id")
private Set<Town> towns;
}
#Entity
#Table(name = "towns")
#Setter
#Getter
public class Town {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "town_id")
private Long townId;
#Column(name = "name")
private String name;
#Column(name = "people_count")
private String peopleCount;
#Column(name = "st_id")
private Long stateId;
}
and in querydsl i am trying below query and always failing to retrieve inner collection towns
List<Expression> childGroup = new ArrayList<>();
query.from(countries);
childGroup.addAll(Arrays.asList(countries.name, countries.data, countries.stateJoin));
query.join(countries.stateJoin, State);
childGroup.add(Projections.bean(State.class, name, count, town)
.as((Path) countries.stateJoin));
OR
childGroup.add(Projections.bean(State.class, name, count, list(town)).as((Path) countries.stateJoin));
query.select(fields);
query.where();
final Map<? extends Number, ? extends Object> t =
(Map<? extends Number, ? extends Object>)
query
.limit(pageRequest.getPageSize())
.offset(pageRequest.getOffset())
.distinct()
.transform(
GroupBy.groupBy(groupByPath)
.as(Projections.bean(Countris.class, childGroup.toArray(new Expression[0]))));
while executing the above line exactly i am getting always SQLSyntax error as i see the underlying SQL is with
. as towns
Can some one help me how to read the nested collection formed by JPA join?
Related
I am new to Spring boot. please help me with the below issue:
I am getting only child object data while retrieving using join query..
Below is my child entity class:
#Entity
#Table(name = "tenant_user_configuration")
public class TenantUserConfiguration {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "config_key")
private String configKey;
#Column(name = "config_value")
private String configValue;
private String system;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="tenant_user_id",referencedColumnName = "tenant_user_id")
#JsonBackReference
private TenantUser tenantUser;
This is my parent entity class:
#Entity
#Table(name = "tenant_user")
public class TenantUser {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "tenant_user_id")
private int tenantUserId;
#OneToOne
#JoinColumn(name = "tenant_id",referencedColumnName = "tenant_id")
private Tenant tenant;
#Column(name = "user_name")
private String userName;
#Column(name = "password")
private String password;
#Column(name = "enabled")
private boolean enabled;
#OneToMany(mappedBy = "tenantUser",fetch = FetchType.EAGER)
#JsonManagedReference
private Set<TenantUserConfiguration> tenantUserConfiguration = new HashSet<>();
I have Company entity:
#Entity
#Data
public class Company {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "company_id", nullable = false, unique = true)
private int companyId;
#Column(name = "name", nullable = false, length = 255, unique = true)
private String name;
#JsonIgnore
#OneToMany (mappedBy = "company")
private List<Employee> employeeList;
}
And Employee entity:
#Entity
#Data
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "employee_id", nullable = false, unique = true)
private int employeeId;
#Column(name = "employee_name", nullable = false)
private String name;
#ManyToOne(optional = false)
#JoinColumn(name = "company_id", nullable = false)
private Company company;
}
I have trouble when I'm mapping EmployeeRequest to Employee object.
This is EmployeeRequest:
#Data
public class EmployeeRequest {
private String name;
private int companyId;
}
As you can see here in request I have companyId which is integer and therefore I have error.
My mapper:
#Component
public class EmployeeMapper {
private Mapper mapper = DozerBeanMapperBuilder.buildDefault();
public Employee transformToEmployeeEntity(EmployeeRequest employeeRequest) {
return mapper.map(employeeRequest, Employee.class);
}
}
I think it makes sense to have an integer as data type in EmployeeRequest. So what is proper way to solve this?
I have 3 entities :
#Entity
#Table(name = "copy")
public class Copy {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Long id;
#Column(name = "format")
private String format;
#Column(name = "status")
private String status;
#ManyToOne
#JoinColumn(name = "book_id")
private Book book;
#ManyToOne
#JoinColumn(name = "library_id")
private Library library;
#Entity
#Table(name = "book")
public class Book implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Long id;
#Column(name = "title")
private String title;
#Column(name = "pub_date")
private Date pubDate;
#Column(name = "page")
private int page;
#Column(name = "synopsis")
private String synopsis;
//TODO Image à gérer
#Column(name = "cover")
private String cover;
#ManyToOne
#JoinColumn(name = "categorie_id")
private Categorie categorie;
#ManyToOne
#JoinColumn(name = "author_id")
private Author author;
#OneToMany(mappedBy = "book")
List<Copy> copyList = new ArrayList<>();
#Entity
#Table(name = "library")
public class Library implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Long id;
#Column(name = "nom")
private String nom;
#Column(name = "adress")
private String adress;
#Column(name = "phone_num")
private String phoneNum;
#Column(name = "email")
private String email;
#OneToMany(mappedBy = "library")
private List<Copy> copyList = new ArrayList<>();
I would like to recover the number of copies of a book according to its format and its libraries. However I cannot figure out how to retrieve a list of copies and the total number depending on the format and its library. How can I do. I wrote this request but I can't get what I want.
My request :
#Query("SELECT DISTINCT c, COUNT(c.format) FROM Copy c WHERE c.book.id = :id")
List<Copy> getCopyById(#Param("id") Long id);
first you need to create class to handel query result (copy,total)
public class CopyWithTotal{
Copy c;
int total;
CopyWithTotal(Copy c, int total){
this.c = c;
this.total = total;
}
}
then you should constratc this class in the query
#Query("SELECT new packgeTo.CopyWithTotal(DISTINCT c, COUNT(c.format)) FROM Copy c WHERE c.book.id = :id group by c")
List<CopyWithTotal> getCopyById(#Param("id") Long id);
whenever you use aggregation function like count all selected column shoud apper in the group by
I hae 2 simple entities: Student and Class. I want to POST a student, where I specify the class it belongs to, but I've got stuck in hibernate mapping.
ClassModel.class
#Entity
#Table(name = "class" )
public class ClassModel implements Serializable {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#NotEmpty
#Size(max = 20)
#Column(name = "name")
private String name;
#Column(name = "tables")
private int tables;
#Column(name = "chairs")
private int chairs;
#Column(name = "teacher")
private String teacher;
(getters + setters)
StudentModel
#Entity
#Table(name = "student")
public class StudentModel implements Serializable {
#Id
#Column(name = "student_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int student_id;
#NotEmpty
#Column(name = "name")
#Size(max = 50)
private String name;
#Column(name = "age")
private int age;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id")
private ClassModel classModel;
(getters + setters)
}
StudentController.java
...
#Autowired
private StudentService studentService;
#Autowired
private ClassService classService;
#PostMapping(value = "/save")
public StudentModel save(#RequestBody StudentModel studentModel){
ClassModel classModel = classService.findById(studentModel.getClassId()).get();
studentModel.setClassModel(classModel);
return studentService.save(studentModel);
}
...
But when I make a request from Postman with the following body:
{
"name": "some name",
"age": 12,
"class_id": 1
}
I get the following error from hibernate:
Column 'class_id' cannot be null
Where is the mistake in my hibernate mapping?
It's how I have made working join in hibernate. Have a look:
TrainingEntity.java
#Id
private Integer id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "animal_id", nullable = false, insertable = false, updatable = false)
private AnimalEntity animalEntity;
#Column(name = "animal_id")
private Integer animalId;
AnimalEntity.java
#Id
private Integer id;
#OneToMany(mappedBy = "animalEntity", fetch = FetchType.LAZY)
private List<TrainingEntity> trainingEntityList = new ArrayList<>();
So here is the join between AnimalEntity and TrainingEntity.
AnimalEntity have a list of TrainingEntities.
The mistake is in this line:
"class_id": 1
You're using column name instead of field name. You would have to replace class_id with classModel, where classModel would be an object. Other solution would be to find ClassModel by id from json and set it as parent to StudentModel.
I have some big problems with making a proper mapping for delivered diagram. It looks like this:
Now, so far I did this, hopefully its ok (ommited getters/setters). You'll notice that USERS has DOMAIN_ID, ignore it as it is not full diagram.
FunctionalityGroup
#Entity
#Table(name = "FUNCTIONALITY_GROUP")
public class FunctionalityGroup implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "FUNCTIONALITY_GROUP_ID")
private Long functionalityGroupId;
#Column(name = "FUNCTIONALITY_GROUP_NM")
private String functionalityGroupName;
#Column(name = "FUNCTIONALITY_GROUP_DESC")
private String functionalityGroupDesc;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "funcionalityGroupId")
private List<Functionality> functionalityList;
}
Functionality
#Entity
#Table(name = "FUNCTIONALITY")
public class Functionality implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "FUNCTIONALITY_ID")
private Long functionalityId;
#Column(name = "FUNCTIONALITY_NM")
private String functionalityGroupName;
#Column(name = "FUNCTIONALITY_DESC")
private String functionalityGroupDesc;
#Column(name = "FUNCTIONALITY_GROUP_ID")
private Long funcionalityGroupId;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "ROLE_FUNCTIONALITY",
joinColumns = {#JoinColumn(name = "FUNCTIONALITY_ID")},
inverseJoinColumns = {#JoinColumn(name = "ROLE_ID")})
private List<Role> roleList;
}
Role
#Entity
#Table(name = "ROLE")
public class Role implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ROLE_ID")
private Integer roleId;
#Column(name = "ROLE_NM")
private String roleName;
#Column(name = "ROLE_DESC")
private String roleDesc;
#Column(name = "OBJECT_TYPE")
private String objectType;
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "roleList")
private List<Functionality> functionalityListy;
}
Users
#Entity
#Table(name = "USERS")
public class Users implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "USER_ID")
private Long userId;
#Column(name = "USER_DESC")
private String userDesc;
#Column(name = "FIRST_NM")
private String firstNM;
#Column(name = "LAST_NM")
private String lastNM;
#Column(name = "IS_ENABLED")
private String isEnabled;
}
I have no idea how Role_Member and Role_Member_Entry should be mapped and handled withing object world, could somebody give me some hits? Thanks!
Normally I'd connect Users with Role as Many to Many, but the entity Role_Member_Entry ruins everything.