Spring Data doesn't update with save() method - java

I'm currently working on an application for an university project. For this project, my team and I are using a Vaadin/Spring/Maven configuration. With this we also include a database connected with repositories.
The repositories are build the following way. First a class for objects:
import javax.persistence.*;
import java.util.Set;
#Entity
#Table (name = "component")
public class Component {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
long id;
String name;
float price;
boolean isVegetarian;
#OneToMany(mappedBy = "component", cascade = {CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.EAGER)
Set<InvoicePosition> Positions;
#ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
ComponentCategory category_id;
String path;
public Component() {
}
public Component(String name, float price, boolean isVegetarian, ComponentCategory category, String path) {
this.name = name;
this.price = price;
this.isVegetarian = isVegetarian;
this.category_id = category;
this.path = path;
}
Then the additional repository:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface ComponentRepository extends JpaRepository<Component, Long>{}
Then there is a repository for component category, in which we should be able to store a list of components:
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Entity
#Table(name = "componentCategory")
public class ComponentCategory {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Long id;
String name;
#OneToMany(mappedBy = "category_id", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
List<Component> components;
public ComponentCategory() { }
public ComponentCategory(String name) {
this.name = name;
components = new ArrayList<>();
}
public void addComponentToCategory(Component component) {
if(!components.contains(component))
{
components.add(component);
component.category_id = this;
}
}
And then the same repository:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface ComponentCategoryRepository extends JpaRepository<ComponentCategory, Long> {}
I am able to create new entries and they are also properly stored in the database. This is all stored in the Application.Java file to start the Vaadin application
ComponentCategory cat1 = new ComponentCategory("examp1");
Component test1 = new Component("example1", 1.25f, true, cat1, "");
Component test2 = new Component("example2", 0.89f, true, cat1, "");
cat1.addComponentToCategory(test1);
cat1.addComponentToCategory(test2);
compcatrep.saveAndFlush(comp); // compcatrep is the ComponentCategoryRepository, which is passed on to the init() function
Now I'm trying to update the entries in the database with the following logic:
Component test11 = new Component("Test", 2.15f, true, compcatrep.getOne((long)4), "");
ComponentCategory comp = compcatrep.getOne((long)4);
comp.addComponentToCategory(test11);
compcatrep.saveAndFlush(comp);
I made sure that there is an entry with the ID (long) 4. It does work and does not show me any error, when I execute the application. Also if I check the length of the stored list in the ComponentCategory after the saveAndFlush():
System.out.println(comp.getComponents().size());
System.out.println(compcatrep.getOne((long)4).getComponents().size());
I do receive different length of the lists. The second Syso does show one less then the first. I tried a lot and did not find the error. Some more information about my issue:
ApplicationProperties in target folder:
spring.datasource.url=jdbc:h2:file:./mensarioDB;DB_CLOSE_ON_EXIT=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.hs-augsburg.bpap</groupId>
<artifactId>mensario</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mensario</name>
<description>mensario management</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<vaadin.version>8.1.0</vaadin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>${vaadin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

Related

java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration~~~~ error

I am working on java spring shopping mall project. I want to fix this error.
Below is my code.
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration#4768b95c testClass = com.maven_shopping.repository.ItemRepositoryTest, locations = [], classes = [com.maven_shopping.MavenShoppingApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = ["classpath:application-test.properties"], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#4e268090, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer#5939a379, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer#1f97cf0d, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer#9da1, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#44821a96, org.springframework.boot.test.context.SpringBootTestAnnotation#9346081e], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Item.java:
package com.maven_shopping.entity;
import com.maven_shopping.constant.ItemSellStatus;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDateTime;
#Entity
#Table(name = "item")
#Getter
#Setter
#ToString
public class Item {
#Id
#Column(name = "item_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false, length = 50)
private String itemName;
#Column(name = "price", nullable = false)
private int price;
#Column(nullable = false)
private int stockNum;
#Lob
#Column(nullable = false)
private String itemDetail;
#Enumerated(EnumType.STRING)
private ItemSellStatus itemSellStatus;
private LocalDateTime regTime;
private LocalDateTime updateTime;
}
ItemRepositoryTest :
package com.maven_shopping.repository;
import com.maven_shopping.constant.ItemSellStatus;
import com.maven_shopping.entity.Item;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.\*;
#SpringBootTest
#TestPropertySource(locations = "classpath:application-test.properties")
class ItemRepositoryTest {
#Autowired
ItemRepository itemRepository;
#Test
#DisplayName("상품 저장 테스트")
public void createItemTest() {
Item item = new Item();
item.setItemName("Test Product");
item.setPrice(10000);
item.setItemDetail("Test Product Detail");
item.setItemSellStatus(ItemSellStatus.SELL);
item.setStockNum(100);
item.setRegTime(LocalDateTime.now());
item.setUpdateTime(LocalDateTime.now());
Item savedItem = itemRepository.save(item);
System.out.println(savedItem.toString());
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.maven_shopping</groupId>
<artifactId>maven_shopping</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>maven_shopping</name>
<description>maven_shopping project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.6.Final</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.properties:
#port setting
server.port=80
#MySQL connect setting
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost::3306/shop?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=****
#show query console
spring.jpa.properties.hibernate.show_sql=true
#query hibernate formatting
spring.jpa.properties.hibernate.format_sql=true
#question mark parameter
logging.level.org.hibernate.type.descriptor.sql=trace
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
##Thymeleaf cache ????
#spring.thymeleaf.check-template-location=true
#spring.thymeleaf.prefix=classpath:templates/
#spring.thymeleaf.suffix=.html
#spring.thymeleaf.cache=false
spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.jdbc-url=jdbc:mysql://localhost:3306/shop
spring.datasource.hikari.username=root
spring.datasource.hikari.password=****
spring.datasource.hikari.pool-name=TestHikariPool
application-test.properties :
# DataSource Setting
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=sa
spring.datasource.password=
#h2 Database dialect Setting
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
application.yml
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/jpashop;
// MVCC=TRUE : 여러개의 요청이 들어왔을때, 빠르게 처리할 수 있도록 도와줌
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create
#애플리케이션 실행시점에 내가 가진 SQL문을 다 지우고, 다시 생성함
properties:
hibernate:
show_sql: true
# System.out.println을 통해 sql문이 출력됨 -> 로그로 출력하게 해야함!
format_sql: true
logging.level:
org.hibernate.SQL: debug
org.hibernate.type: trace

Postman Get request returns duplicate results

When I issue a Postman Get request, it returns duplicate result. Even when I had only three records in my database, Postman returns hundreds of same record duplicated.
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.resource</groupId>
<artifactId>akademiks</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>akademiks</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Entity class:
#Entity
#Table(name = "Chemistry")
public class Chemistry {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "date")
private Date date;
#Column(name = "question_no")
private Integer questionNo;
#Column(name = "question")
private String question;
#OneToOne(mappedBy = "question",cascade = CascadeType.ALL)
private ChemistryAnswer answer = new ChemistryAnswer();
public Chemistry() {}
public Chemistry(Date date, Integer questionNo, String question) {
this.date = date;
this.questionNo = questionNo;
this.question = question;
this.answer.setDate(date);
this.answer.setQuestionNo(questionNo);
this.answer.setQuestion(this);
}//accessors
Entity class:
#Entity
#Table(name = "Chemistryanswer")
public class ChemistryAnswer {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "date")
private Date date;
#Column(name = "question_no")
private Integer questionNo;
#Column(name = "solution")
private String solution;
#Column(name = "solution_url")
private String solutionUrl;
#OneToOne
#JoinColumn(name = "question_id")
private Chemistry question;
public ChemistryAnswer() {}
public ChemistryAnswer(Integer questionNo, String solution, String solutionUrl) {
this.questionNo = questionNo;
this.solution = solution;
this.solutionUrl = solutionUrl;
}
public ChemistryAnswer(Date date, Integer questionNo) {
this.date = date;
this.questionNo = questionNo;
}
public Date getDate() {
return date;
}//accessors
jpaRepository:
#RepositoryRestResource(collectionResourceRel = "chemistry", path = "chemistry")
public interface ChemistryRepo extends JpaRepository<Chemistry, Integer> {
}
Service class:
public interface ChemistryService {
public List<Chemistry>findAll();
public void save(Chemistry chemistry);
}
Service implementation:
#Service
public class ChemistryServiceImpl implements ChemistryService {
private ChemistryRepo repo;
public ChemistryServiceImpl() {}
#Autowired
public ChemistryServiceImpl(ChemistryRepo repo) {
this.repo = repo;
}
#Override
public List<Chemistry> findAll() {
return repo.findAll();
}
#Override
public void save(Chemistry chemistry) {
Chemistry tempChemistry = new Chemistry(chemistry.getDate(),
chemistry.getQuestionNo(), chemistry.getQuestion());
ChemistryAnswer answer = tempChemistry.getAnswer();
tempChemistry.setAnswer(answer);
repo.save(tempChemistry);
}
}
RestController class:
#RestController
public class ChemistryController {
private ChemistryService service;
#Autowired
public ChemistryController(ChemistryService service) {
this.service = service;
}
#GetMapping("/chemistries")
public ResponseEntity<Object>findAll(){
return new ResponseEntity<Object>(service.findAll(), HttpStatus.OK);
}
#PostMapping("/chemistry")
public void save(#RequestBody Chemistry chemistry,
HttpServletResponse response) throws IOException {
service.save(chemistry);
response.sendRedirect("/chemistries");
}
}
Stacktrace Get request:
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.5.jar:2.12.5]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.5.jar:2.12.5]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.5.jar:2.12.5]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.5.jar:2.12.5]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.5.jar:2.12.5]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.5.jar:2.12.5]
The issue you are facing is quite abstract. "Postman returns hundreds of same record duplicated." does not tell us much. Still, I guess that the issue is your bi-directional relationship. Try adding #JsonManagedReference and #JsonBackReference to your bi-directional relationship in your model as follows:
#JsonManagedReference
#OneToOne(mappedBy = "question",cascade = CascadeType.ALL)
private ChemistryAnswer answer = new ChemistryAnswer();
#OneToOne
#JsonBackReference
#JoinColumn(name = "question_id")
private Chemistry question;

How to use MapStruct #Mapping and #Mappings properly?

hi my problem is when i do mvn clean package to build .jar files, i got some error that looked like this :
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /C:/Users/Cactus/Documents/GitHub/Microservice/b2b/b2b-warehouse/src/main/java/com/bit/microservices/b2b/warehouse/mapper/ICategoryBpsjMapper.java:[27,33] No property named "createdDate" exists in source parameter(s). Did you mean "reasonDeleted"?
[ERROR] /C:/Users/Cactus/Documents/GitHub/Microservice/b2b/b2b-warehouse/src/main/java/com/bit/microservices/b2b/warehouse/mapper/ICategoryBpsjMapper.java:[27,33] No property named "createdDate" exists in source parameter(s). Did you mean "reasonDeleted"?
[INFO] 2 errors
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16.438 s
[INFO] Finished at: 2020-11-30T10:55:21+07:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project b2b-warehouse: Compilation failure: Compilation failure:
[ERROR] /C:/Users/Cactus/Documents/GitHub/Microservice/b2b/b2b-warehouse/src/main/java/com/bit/microservices/b2b/warehouse/mapper/ICategoryBpsjMapper.java:[27,33] No property named "createdDate" exists in source parameter(s). Did you mean "reasonDeleted"?
[ERROR] /C:/Users/Cactus/Documents/GitHub/Microservice/b2b/b2b-warehouse/src/main/java/com/bit/microservices/b2b/warehouse/mapper/ICategoryBpsjMapper.java:[27,33] No property named "createdDate" exists in source parameter(s). Did you mean "reasonDeleted"?
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
but when i run my project through Boot Dashboard with right click and start my project it run normally. and my api work fine. i do some try.
first trying my code is looked like below, i have mapper file that looked like this :
#Mapper(componentModel = "spring")
public interface ICategoryBpsjMapper {
ICategoryBpsjMapper INSTANCE = Mappers.getMapper(ICategoryBpsjMapper.class);
#Mappings({
#Mapping(target = "createdDate", dateFormat = "dd-MM-yyyy HH:mm:ss"),
#Mapping(target = "modifiedDate",dateFormat = "dd-MM-yyyy HH:mm:ss")})
CategoryBpsjResponseDto entityToDto(CategoryBPSJ entity);
CategoryBPSJ DTOEntity(CategoryBPSJDto dto);
CategoryBPSJ updateEntityFromDto(CategoryBPSJDto dto, #MappingTarget CategoryBPSJ entity);
List<CategoryBpsjResponseDto> entityToDto(List<CategoryBPSJ> entityList);
List<CategoryBPSJ> DTOEnity(List<CategoryBPSJDto> dtoList);
}
and here is my entity :
#Data
#Entity
#Audited
#EntityListeners(AuditingEntityListener.class)
#EqualsAndHashCode(of = "id")
#ToString(of = {"id"})
#Table(name = "msCategoryBPSJ", uniqueConstraints = {
#UniqueConstraint(name = "uk_categoryBPSJName", columnNames = { "categoryBPSJName" })})
public class CategoryBPSJ extends AuditField implements Serializable {
private static final long serialVersionUID = 8062436315663828938L;
#Schema(description = "Id merupakan primary key dan harus disertakan ketika edit, tipe datanya Long", example = "0", required = true)
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Schema(description = "kode kategori pengiriman", example = "BPSJCTH1", required = true)
#NotBlank(message = "Tidak Boleh Kosong")
private String categoryBPSCode;
#Schema(description = "nama kategori pengiriman", example = "Toko/Gudang Tujuan Tutup", required = true)
#NotBlank(message = "Tidak Boleh Kosong")
private String categoryBPSJName;
}
and here is my extended AuditField class :
#MappedSuperclass
#Data
#Audited
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = { "createdDate", "modifiedDate", "isDeleted" }, allowGetters = true, allowSetters = false)
public class AuditField implements Serializable {
private static final long serialVersionUID = 6025082509703710749L;
#Schema(description = "Status di hapus", example = "false", required = false)
public Boolean isDeleted = false;
#Schema(description = "Alasan di hapus", example = "apa pun alasannya", required = false)
public String reasonDeleted = "";
#CreatedDate
private Date createdDate;
#LastModifiedDate
private Date modifiedDate;
#CreatedBy
private String createdBy;
#LastModifiedBy
private String modifiedBy;
}
and here is my DTO AuditFieldDto class :
#Data
public class CategoryBpsjResponseDto extends AuditFieldDto implements Serializable {
private static final long serialVersionUID = -422185482845439241L;
#Schema(description = "Id merupakan primary key dan harus disertakan ketika edit, tipe datanya Long", example = "0", required = true)
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
#Schema(description = "kode kategori pengiriman", example = "BPSJCTH1", required = true)
#NotBlank(message = "Tidak Boleh Kosong")
public String categoryBPSCode;
#Schema(description = "nama kategori pengiriman", example = "Toko/Gudang Tujuan Tutup", required = true)
#NotBlank(message = "Tidak Boleh Kosong")
public String categoryBPSJName;
}
and here is my AuditFieldDto class :
#Data
public class AuditFieldDto implements Serializable {
private static final long serialVersionUID = 3758121148184815303L;
#Schema(description = "Status di hapus", example = "false", required = false)
public Boolean isDeleted = false;
#Schema(description = "Alasan di hapus", example = "apa pun alasannya", required = false)
public String reasonDeleted = "";
private String createdDate;
private String modifiedDate;
private String createdBy;
private String modifiedBy;
}
As you can see the AuditField and AuditFieldDto have the same field, but when i do run mvn clean package it give me COMPILATION ERROR like the top of my question mentioned. in the error message it seems to mapstruct cannot find the field properly. Then i try to remove #Mappings and #Mapping annotation line, the build is success. seems fishy.. because when i run with Boot Dashboard is working fine with those annotation.
here is my pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bit.microservices</groupId>
<artifactId>b2b</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>b2b-warehouse</artifactId>
<groupId>com.bit.microservices.b2b</groupId>
<name>b2b-warehouse</name>
<description>B2B Warehouse Service</description>
<version>0.0.1-SNAPSHOT</version>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
<lombok.version>1.18.16</lombok.version>
<org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>com.bit.microservices</groupId>
<artifactId>model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-envers</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.bit.b2b</groupId>
<artifactId>security</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.4.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.classgraph/classgraph -->
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>4.8.90</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.8</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>13</source> <!-- depending on your project -->
<target>13</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.3.4.RELEASE</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
What i missed in my project if i want to use #Mappings and #Mapping when i build my project to .jar files with mvn clean package?
i found the culprit here, but i am not sure why and is this the right things to do, since when i do this code, it worked. okay lets start, you can check my mapstruct version at my question, and here is how i fixed this :
first of all, in my AuditField and AuditFieldDto, as you can see i have 2 field that written in "public" data type, at first i write all of my field in public but then my friend come and refer me to make it private, but i accidentally i don't make all of it private, the two fields named public Boolean isDeleted; and public String reasonDeleted; is public, that's why the error go through them, they work fine and the error go to my another line that written in private.
and i just random miserably changed their data type back into public, as you can see there is 4 field that written in private fields, they are
#CreatedDate
private Date createdDate;
#LastModifiedDate
private Date modifiedDate;
#CreatedBy
private String createdBy;
#LastModifiedBy
private String modifiedBy;
so i changed all of them into public in my AuditFieldDto and AuditField class, the complete of code of my AuditField class is looked like this :
#MappedSuperclass
#Data
#Audited
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = { "createdDate", "modifiedDate", "isDeleted" }, allowGetters = true, allowSetters = false)
public class AuditField implements Serializable {
private static final long serialVersionUID = 6025082509703710749L;
#Schema(description = "Status di hapus", example = "false", required = false)
public Boolean isDeleted;
#Schema(description = "Alasan di hapus", example = "apa pun alasannya", required = false)
public String reasonDeleted;
#CreatedDate
public Date createdDate;
#LastModifiedDate
public Date modifiedDate;
#CreatedBy
public String createdBy;
#LastModifiedBy
public String modifiedBy;
}
it's apply the same for my AuditFieldDto class, which is looked like this :
#Data
public class AuditFieldDto implements Serializable {
private static final long serialVersionUID = 3758121148184815303L;
#Schema(description = "Status di hapus", example = "false", required = false)
public Boolean isDeleted = false;
#Schema(description = "Alasan di hapus", example = "apa pun alasannya", required = false)
public String reasonDeleted = "";
public String createdDate;
public String modifiedDate;
public String createdBy;
public String modifiedBy;
}
and when i do run mvn clean package the build is a success! and i ran the .jar files, it working! i guess why??? i stuck for days because of this. then i try to look into the generated files, you can find the generated files in your project located at target/generated-sources/annotations and fine the mapper class file. And here is mine, i only take one example of the generated code, since the other seems doesn't have any problem.
here is what inside the GENERATED FILE (we shouldn't edit this file, just for view) :
#Component
public class ICategoryBpsjMapperImpl implements ICategoryBpsjMapper {
#Override
public CategoryBpsjResponseDto entityToDto(CategoryBPSJ entity) {
if ( entity == null ) {
return null;
}
CategoryBpsjResponseDto categoryBpsjResponseDto = new CategoryBpsjResponseDto();
if ( entity.createdDate != null ) {
categoryBpsjResponseDto.createdDate = new SimpleDateFormat( "dd-MM-yyyy HH:mm:ss" ).format( entity.createdDate );
}
if ( entity.modifiedDate != null ) {
categoryBpsjResponseDto.modifiedDate = new SimpleDateFormat( "dd-MM-yyyy HH:mm:ss" ).format( entity.modifiedDate );
}
categoryBpsjResponseDto.isDeleted = entity.isDeleted;
categoryBpsjResponseDto.reasonDeleted = entity.reasonDeleted;
categoryBpsjResponseDto.createdBy = entity.createdBy;
categoryBpsjResponseDto.modifiedBy = entity.modifiedBy;
return categoryBpsjResponseDto;
}
}
you see they access the property without get and set (i mean getter setter), i think this is the culprit that cause my error since when i marked the field as private, and if the code is written like that, they won't can be accessed. for now this is the way i solved it.
if someone have better answer, i will take their answer as accepted answer, if mine code not right or appropriate, waiting for it.
I think you're missing the lombok-mapstruct-binding.

#EnableJpaRepositories is not present in spring boot 2.1.4.RELEASE

I created a project using spring boot 2.1.4.RELEASE with the following dependencies:
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
I have the following entity and repository:
#Entity
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "name")
private String name;
#Column(name = "last_name")
private String lastName;
#Column(name = "age")
private Integer age;
#Column(name = "createdAt")
#Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
...
}
PersonRepository.java
#Repository
public interface PersonRepository extends CrudRepository<Person, Integer> {
}
The following is my Application class:
#SpringBootApplication
public class SpringDataApplication {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(SpringDataApplication.class, args);
PersonRepository personRepository = context.getBean(PersonRepository.class);
Person p1 = new Person("Juan", "Camaney", 55);
Person p2 = new Person("Arturo", "Lopez", 33);
Person p3 = new Person("Pancho", "Coscorin", 22);
personRepository.save(p1);
personRepository.save(p2);
personRepository.save(p3);
Iterator<Person> people = personRepository.findAll().iterator();
while (people.hasNext()) {
Person temp = people.next();
System.out.println(temp);
}
}
}
If i execute my application i get the following error:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.devs4j.spring.data.repositories.PersonRepository' available
The solution of it is add the following configuration class:
#Configuration
#EnableJpaRepositories("com.devs4j.spring.data.repositories")
public class JpaConfiguration {
}
But I get the error :
EnableJpaRepositories cannot be resolved to a type
If i downgrade to 2.0.5.RELEASE everything works fine.
I'm confused because when i check the following spring documentation https://docs.spring.io/spring-data/jpa/docs/2.1.6.RELEASE/reference/html/ I see that it is still using #EnableJpaRepositories("com.acme.repositories")
Am i doing something wrong ?
In your configuration.java, have you added the import:
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

Error executing DDL via JDBC Statement in Spring-MVC project

I'm trying to run my Java Spring MVC project application, but I get the following error (I have connectted my MySql database to the project):
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL via JDBC Statement
which is caused by:
Caused by: java.sql.SQLException: Cannot add foreign key constraint
The foreign key problem above is about the "OrderItems" Entity in my database, here is its code:
package com.example.WebAppProcess20.Entities;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Table(name = "ordersitems", schema = "theprocess")
#IdClass(OrdersitemsEntityPK.class)
public class OrdersitemsEntity {
private String orderId;
private String productId;
private Integer qunatity;
private OrdersEntity ordersByOrderId;
#Id
#Column(name = "orderId")
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
#Id
#Column(name = "product_id")
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
#Basic
#Column(name = "qunatity")
public Integer getQunatity() {
return qunatity;
}
public void setQunatity(Integer qunatity) {
this.qunatity = qunatity;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrdersitemsEntity that = (OrdersitemsEntity) o;
return Objects.equals(orderId, that.orderId) &&
Objects.equals(productId, that.productId) &&
Objects.equals(qunatity, that.qunatity);
}
#Override
public int hashCode() {
return Objects.hash(orderId, productId, qunatity);
}
#ManyToOne
#JoinColumn(name = "orderId", referencedColumnName = "orderId", nullable = false, updatable = false, insertable = false)
public OrdersEntity getOrdersByOrderId() {
return ordersByOrderId;
}
public void setOrdersByOrderId(OrdersEntity ordersByOrderId) {
this.ordersByOrderId = ordersByOrderId;
}
}
This Entity specifies the products included in each order, therefore it has two foreign keys - productId and OrderId.
also adding the pom.xml and hibernate.cfg.xml files if necessary:
hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/theprocess?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC</property>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- DB schema will be updated if needed -->
<property name="hbm2ddl.auto">update</property>
<mapping class="com.example.WebAppProcess20.Entities.ClientsEntity"/>
<mapping class="com.example.WebAppProcess20.Entities.InvoicesEntity"/>
<mapping class="com.example.WebAppProcess20.Entities.OrdersEntity"/>
<mapping class="com.example.WebAppProcess20.Entities.OrdersitemsEntity"/>
<mapping class="com.example.WebAppProcess20.Entities.ProductsEntity"/>
</session-factory>
</hibernate-configuration>
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>WebAppProcess2.0</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>WebAppProcess2.0</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Can you please explain what the problem is?
Thanks!

Categories

Resources