Why allocationSize was not considered in H2 spring boot - spring-boot

For my spring boot, I created the following query in data.sql file.
INSERT into ROOM( id, title, room_size) values (1, 'Green', 20);
INSERT into ROOM( id, title, room_size) values (2, 'Blue', 50);
now for my Room Entity, I created the below class
#Entity(name = "room")
#Getter
#Setter
#NoArgsConstructor
#FieldDefaults(level = AccessLevel.PRIVATE)
#EntityListeners(AuditingEntityListener.class)
public class Room {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_room_id")
#SequenceGenerator(name = "seq_room_id",allocationSize = 1)
Long id;
String title;
#Column(name = "room_size")
Long roomSize;
#CreatedDate
LocalDateTime createdOn;
}
but when I tried to add a new Room it is giving me a ConstrainViolation exception as it is trying to add a room with id 1 again ignoring to check allocationSize=1
How to solve this?

Related

Table name like SQL syntax in Spring boot

I can't create table order because table name match sql syntax. How can I resolve it? Is there any property in application.properties support it?
#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "order")
public class Order {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(nullable = false)
private Double productPrice;
#Column(nullable = false)
private Double shipPrice;
#Column(nullable = false)
private Integer status;
}
Use
#Table(name="\"order\"")

Entity A has OneToOne relation with Entity B, when a data is inserted in A, entity B also gets inserted the same id as A

So, I have a Student entity and a ShoppingCart entity.
What I wanted to achieve is, when I insert data for student, let's say studentId = 1, the cartId automatically has 1 inserted. For example:
Student table
student_id
full_name
1
Foo
2
Bar
When these 2 students are created, the shopping cart table automatically becomes:
Shopping cart table
cart_id
1
2
These are my Student and Cart entities.
Student.java
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
#Table(name = "student", uniqueConstraints = {
#UniqueConstraint(name = "uc_student_email_address", columnNames = {"email_address"})
public class Student {
#Id
#SequenceGenerator(
name = "student_sequence",
sequenceName = "student_sequence",
allocationSize=1
)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "student_sequence")
private Long studentId;
private String fullName;
#Column(name = "email_address", nullable = false)
private String email;
private String username;
private String password;
ShoppingCart.java
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
public class ShoppingCart {
#Id
private Long cartId;
#OneToOne
#MapsId
#JoinColumn(name = "cart_id", referencedColumnName = "studentId")
private Student student;
So, how do I achieve this?
Thanks in advance.

Multiple list of Data comming in API when using ManyToOne Relationship

CarMake.java
#Getter
#Setter
#EqualsAndHashCode
#NoArgsConstructor
#Entity
public class CarMake {
#SequenceGenerator(
name = "car_make_sequence",
sequenceName = "car_make_sequence",
allocationSize = 1
)
#Id
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "car_make_sequence"
)
private Long id;
private String name;
#CreationTimestamp
private LocalDateTime createdAt;
#UpdateTimestamp
private LocalDateTime updatedAt;
#OneToMany(mappedBy = "make", cascade = CascadeType.ALL)
private List<CarModel> model;
}
CarModel.java
#Getter
#Setter
#EqualsAndHashCode
#NoArgsConstructor
#Entity
public class CarModel {
#SequenceGenerator(
name = "car_model_sequence",
sequenceName = "car_model_sequence",
allocationSize = 1
)
#Id
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "car_model_sequence"
)
private Long id;
private String name;
private Integer beginDate;
private Integer endDate;
#CreationTimestamp
private LocalDateTime createdAt;
#UpdateTimestamp
private LocalDateTime updatedAt;
#ManyToOne(fetch = FetchType.EAGER)
CarMake make;
#OneToMany(mappedBy = "model", cascade = CascadeType.ALL)
private List<CarVariant> variants;
}
CarVariant.java
#Getter
#Setter
#EqualsAndHashCode
#NoArgsConstructor
#Entity
public class CarVariant {
#SequenceGenerator(
name = "car_variant_sequence",
sequenceName = "car_variant_sequence",
allocationSize = 1
)
#Id
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "car_variant_sequence"
)
private Long id;
#Column(nullable = false)
private String name;
#CreationTimestamp
private LocalDateTime createdAt;
#UpdateTimestamp
private LocalDateTime updatedAt;
#ManyToOne(fetch = FetchType.LAZY)
CarModel model;
}
If i am using repository i am getting loop of data which is not present even in database
#GetMapping("api/car/model/{id}")
#ResponseBody
public Iterable<CarMake> showCarModelsByMakeId(#PathVariable Long id){
return carMakeRepository.findAll();
}
Bellow is the response of API
[{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983",
I beleive i should get only one instance of data as only one row is present in table. what is the reason i am getting so much data, did i created onetomany relationship correctly?, how i can achieve it
Database data
This is a famous bidirectional issue. In few words, your CarMake entity references CarModel, which in its turn, references back to CarMake, what causes an infinitive loop.
Try to put #JsonIgnore annotation on CarMake make in your CarModel entity and repeat the test.
PS: better to not to return entity objects from your rest controller, use either DTO mapping, or projections
PPS: don't use #EqualsAndHashCode on #Entity classes

Sequence generator in h2 does not provide unique values

For H2 database in my spring boot api test there is an insertion script that looks something like:
INSERT INTO STORES_TEMPLATE (ID, COUNTRY, TEMPLATE_NAME_1, STORES_1) VALUES(STORES_TEMPLATE_ID_SEQ.NEXTVAL,'country', 'template_name', 'stores');
INSERT INTO STORES_TEMPLATE (ID, COUNTRY, TEMPLATE_NAME_2, STORES_2) VALUES(STORES_TEMPLATE_ID_SEQ.NEXTVAL,'country', 'template_name', 'stores');
INSERT INTO STORES_TEMPLATE (ID, COUNTRY, TEMPLATE_NAME_3, STORES_3) VALUES(STORES_TEMPLATE_ID_SEQ.NEXTVAL,'country', 'template_name', 'stores');
The entity:
#Entity
#Getter
#Setter
#NoArgsConstructor
#Table(name = "STORES_TEMPLATE")
public class StoresTemplate {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "STORES_TEMPLATE_ID_SEQ")
#SequenceGenerator(name = "STORES_TEMPLATE_ID_SEQ", sequenceName = "STORES_TEMPLATE_ID_SEQ", allocationSize = 1)
private Long id;
#Enumerated(EnumType.STRING)
private CountryEnum country;
private String templateName;
#Lob
private String stores;
public void setStores(List<String> stores) {
this.stores = String.join(",", stores);
}
#JsonIgnore
public List<String> getStoresAsList() {
return Arrays.stream(stores.split(","))
.distinct()
.collect(Collectors.toList());
}
}
On production oracle database everything works just fine, but on my test environment with h2 database when I try to save new entity the sequence generator gives me ids that are duplicated with the ids of the predefined by the sql migration data. What can I do to fix this issue?
What did the trick was to exclude the insertion script for the tests, but is there another possible solution?

Spring Framework + Spring Data + Hibernate Jpa OneToMany child removal fails

I have an unidirectional OneToMany JPA entity mapping in my (Spring Framework + Spring Data + Hibernate JPA) project. Entity classes are like in the following code.(I have removed irrelevant class members for brevity).
#Entity
#Table(name = "employees")
class Employee{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name = "employee_id")
private List<DepartmentAssignment> departmentAssignments = new ArrayList<>();
}
#Entity
#Table(name = "department_assignments")
class DepartmentAssignment{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#NotNull
#Column(name = "employee_id")
private Integer employeeId;
#NotNull
#Column(name = "department_id")
private Integer departmentId;
}
#Entity
#Table(name = "departments")
class Department{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
}
And, in one of my service classes have a method to remove a DepartmentAssignment from an Employee like below.
public Employee deleteDepartmentAssignment(Integer empId, Integer deptAssignmentId) {
Employee employee = employeeRepository.findOne(empId);
if(employee != null) {
for ( DepartmentAssignment da : employee.getDepartmentAssignments()) {
if(da.getId().equals(deptAssignmentId)) {
employee.getDepartmentAssignments().remove(da);
employee = employeeRepository.save(employee);
break;
}
}
}
return employee;
}
However, calling above methods gives me an error: org.hibernate.exception.ConstraintViolationException ,and in the SQL log, I can see Column 'employee_id' cannot be null error for the last SQL statement of the transaction.
Can anybody tell me what I'm doing wrong here and how to get it fixed?
You don't need to add
#NotNull
#Column(name = "employee_id")
private Integer employeeId;
to the Employee, if you use #JoinColumn(name = "employee_id"). Try to remove it.
You can try the following, not sure why you use the plain id in the object. Thats not object relational mapping.
For more details see Hibernate triggering constraint violations using orphanRemoval
#Entity
#Table(name = "employees")
class Employee{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "employee", orphanRemoval = true)
private List<DepartmentAssignment> departmentAssignments = new ArrayList<>();
}
#Entity
#Table(name = "department_assignments")
class DepartmentAssignment{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#ManyToOne(optional=false)
private Employee employee;
#ManyToOne(optional=false)
private Department department;
}
#Entity
#Table(name = "departments")
class Department{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
You must look .hbm.xml file and you should mapping your Entity in this file and
you can look this example
http://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example/
I hope it will be useful for you.
try removing
cascade = CascadeType.ALL
but im not 100% sure..

Resources