Spring Boot Data JpaSpecificationExecutor couldn't retrieve data by date time - java

This is my entity class:
#Data
#Entity
#Table(name = "CHECKS")
public class ChecksEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime beginDate;
private Long checkId;
private String courtName;
private LocalDateTime createdDate = LocalDateTime.now();
private String dateOfBirth;
private LocalDateTime decisionDate;
private String decisionNumber;
private LocalDateTime endDate;
private String filePath;
private String judgeName;
private String name;
private String note;
private String patronymic;
private String person;
private String personType;
private String responseData;
private String surname;
}
and this is my JpaSpecificationExecutor class:
#Component
public class ChecksSpecification {
public Specification<ChecksEntity> getChecks(ArchiveOperationRequestDto request) {
return (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (request.getPerson() != null && !request.getPerson().isEmpty()) {
predicates.add(criteriaBuilder.equal(root.get("person"), request.getPerson()));
}
if (request.getDecisionNumber() != null && !request.getDecisionNumber().isEmpty()) {
predicates.add(criteriaBuilder.equal(root.get("decisionNumber"), request.getDecisionNumber()));
}
if (request.getCourtName() != null && !request.getCourtName().isEmpty()) {
predicates.add(criteriaBuilder.equal(root.get("courtName"), request.getCourtName()));
}
if (request.getToDate() != null || request.getFromDate() != null) {
// predicates.add(criteriaBuilder.equal(root.get("beginDate"), request.getToDate()));
// predicates.add(criteriaBuilder.equal(root.get("beginDate"), request.getFromDate()));
final Predicate created = criteriaBuilder.equal(root.get("beginDate"), request.getToDate());
return criteriaBuilder.or(created);
}
return criteriaBuilder.or(predicates.toArray(new Predicate[0]));
};
}
}
When I send a request here, it returns data as normal in response, according to all the values I have specified.
This is my send request dto:
#Data
public class ArchiveOperationRequestDto {
private String person;
private String decisionNumber;
private LocalDateTime toDate;
private LocalDateTime fromDate;
private String courtName;
}
It just doesn't return data about toDate and fromDate. It comes empty. What should I do to return data from database by date?

Related

Java JPA SpringBoot removing parent id from one child (Of one specific entity) when parent updates

I've been developing a SpringBoot application, and some entities of the project has OneToMany relationship, which has cascade all, for example:
#OneToMany(mappedBy = "candidate", cascade = CascadeType.ALL, orphanRemoval = true)
#LazyCollection(LazyCollectionOption.FALSE)
private Set<CandidateAcademicEducation> academicEducations;
#OneToMany(mappedBy = "candidate", cascade = CascadeType.ALL, orphanRemoval = true)
#LazyCollection(LazyCollectionOption.FALSE)
private Set<CandidateProfessionalExperience> professionalExperiences;
In all entities, this cascade was working just fine, i was sending the parent object with all related entities (Using JSON), it was being saved, updated and deleted correctly, but specifically on this CandidateAcademicEducation entity, when i update the Candidate entity (Sending the same data present on database to the application, including related entities), for some reason (When the candidate already has academicEducations on database), always one of the AcademicEducations loses candidate's id (If i send 1 academicEducation, it just loses candidate's id. If i send 3, 2 of them stay with parent's id and the other loses).
I've been reading and re-reading the code a lot, because CandidateProfessionalExperience is working just fine, and i can't find the difference between them.
I've verified preUpdate and postUpdate methods on Candidate entity, and it always has the correct amount of AcademicEducation, with the data and reference to Candidate entity correctly setted.
EntityDTO:
public abstract class EntityDTO<Entity> implements Comparable<EntityDTO<Entity>> {
#JsonProperty(access = Access.READ_ONLY)
protected Long id;
public EntityDTO() {
super();
}
public EntityDTO(Long id) {
this.id = id;
}
public static<T, K extends EntityDTO<T>> T getParsedEntity(
K entityDTO
) {
if(entityDTO == null) return null;
return entityDTO.toEntity();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int compareTo(EntityDTO<Entity> entityDTO) {
if(entityDTO == null) return -1;
boolean idIsNull = id == null;
boolean receivedIdIsNull = entityDTO.getId() == null;
if(idIsNull && receivedIdIsNull) return 0;
if(idIsNull || receivedIdIsNull) return -1;
return id.compareTo(entityDTO.getId());
}
public boolean equals(EntityDTO<Entity> entityDTO) {
return this.compareTo(entityDTO) == 0;
}
public abstract Entity toEntity();
}
Candidate entity:
#Entity
#Table(name = "candidates")
public class Candidate {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String photo;
private String profession;
private String phoneNumber;
private String linkedin;
private String birthDate;
private boolean hasProfessionalExperience;
#ManyToOne
private State state;
#ManyToOne
private City city;
#OneToOne
private User user;
#OneToMany(mappedBy = "candidate", cascade = CascadeType.ALL, orphanRemoval = true)
#LazyCollection(LazyCollectionOption.FALSE)
private Set<CandidateAcademicEducation> academicEducations;
#OneToMany(mappedBy = "candidate", cascade = CascadeType.ALL, orphanRemoval = true)
#LazyCollection(LazyCollectionOption.FALSE)
private Set<CandidateProfessionalExperience> professionalExperiences;
#CreationTimestamp
#Column(updatable = false)
private Date createdAt;
#UpdateTimestamp
private Date updatedAt;
public Candidate() {
super();
}
public Candidate(
Long id, String photo, String profession,
String phoneNumber, String linkedin, String birthDate,
boolean hasProfessionalExperience, State state,
City city, User user, Set<CandidateAcademicEducation> academicEducations,
Set<CandidateProfessionalExperience> professionalExperiences,
Date createdAt, Date updatedAt
) {
this.id = id;
this.photo = photo;
this.profession = profession;
this.phoneNumber = phoneNumber;
this.linkedin = linkedin;
this.birthDate = birthDate;
this.hasProfessionalExperience = hasProfessionalExperience;
this.state = state;
this.city = city;
this.user = user;
this.academicEducations = academicEducations;
this.professionalExperiences = professionalExperiences;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
#PrePersist
#PreUpdate
private void prePersistAndUpdate() {
academicEducations.forEach(academicEducation -> academicEducation.setCandidate(this));
professionalExperiences.forEach(professionalExperience -> professionalExperience.setCandidate(this));
}
}
CandidateDTO:
public class CandidateWithAllRelatedDataDTO extends CandidateDTO {
private SortedSet<CandidateAcademicEducationDTO> academicEducations;
private SortedSet<CandidateProfessionalExperienceDTO> professionalExperiences;
public CandidateWithAllRelatedDataDTO() {
super();
}
public CandidateWithAllRelatedDataDTO(
Long id, String photo, String profession,
String phoneNumber, String linkedin,
String birthDate, Boolean hasProfessionalExperience,
StateDTO state, CityDTO city,
SortedSet<CandidateAcademicEducationDTO> academicEducations,
SortedSet<CandidateProfessionalExperienceDTO> professionalExperiences,
Long userId, Date createdAt, Date updatedAt
) {
super(
id, photo, profession, phoneNumber,
linkedin, birthDate, hasProfessionalExperience,
state, city, userId, createdAt, updatedAt
);
this.academicEducations = academicEducations;
this.professionalExperiences = professionalExperiences;
}
public static CandidateWithAllRelatedDataDTO FromEntity(Candidate candidateEntity) {
if(candidateEntity == null) return null;
CandidateWithAllRelatedDataDTO candidateWithAllRelatedDataDTO = new CandidateWithAllRelatedDataDTO();
candidateWithAllRelatedDataDTO.setId(candidateEntity.getId());
candidateWithAllRelatedDataDTO.setPhoto(candidateEntity.getPhoto());
candidateWithAllRelatedDataDTO.setProfession(candidateEntity.getProfession());
candidateWithAllRelatedDataDTO.setPhoneNumber(candidateEntity.getPhoneNumber());
candidateWithAllRelatedDataDTO.setLinkedin(candidateEntity.getLinkedin());
candidateWithAllRelatedDataDTO.setBirthDate(candidateEntity.getBirthDate());
candidateWithAllRelatedDataDTO.setHasProfessionalExperience(candidateEntity.hasProfessionalExperience());
candidateWithAllRelatedDataDTO.setState(StateDTO.FromEntity(candidateEntity.getState()));
candidateWithAllRelatedDataDTO.setCity(CityDTO.FromEntity(candidateEntity.getCity()));
candidateWithAllRelatedDataDTO.setUserId(candidateEntity.getUser().getId());
candidateWithAllRelatedDataDTO.setCreatedAt(candidateEntity.getCreatedAt());
candidateWithAllRelatedDataDTO.setUpdatedAt(candidateEntity.getUpdatedAt());
candidateWithAllRelatedDataDTO.setAcademicEducations(
candidateEntity.getAcademicEducations().stream().map(
academicEducation -> CandidateAcademicEducationDTO.FromEntity(academicEducation)
).collect(Collectors.toCollection(() -> new TreeSet<>()))
);
candidateWithAllRelatedDataDTO.setProfessionalExperiences(
candidateEntity.getProfessionalExperiences().stream().map(
professionalExperience ->
CandidateProfessionalExperienceDTO.FromEntity(professionalExperience)
).collect(Collectors.toCollection(() -> new TreeSet<>()))
);
return candidateWithAllRelatedDataDTO;
}
public void update(CandidateWithAllRelatedDataDTO updatedCandidate) {
String photo = updatedCandidate.getPhoto();
if(photo != null) this.photo = photo;
String profession = updatedCandidate.getProfession();
if(profession != null) this.profession = profession;
String phoneNumber = updatedCandidate.getPhoneNumber();
if(phoneNumber != null) this.phoneNumber = phoneNumber;
String linkedin = updatedCandidate.getLinkedin();
if(linkedin != null) this.linkedin = linkedin;
String birthDate = updatedCandidate.getBirthDate();
if(birthDate != null) this.birthDate = birthDate;
Boolean hasProfessionalExperience = updatedCandidate.hasProfessionalExperience();
if(hasProfessionalExperience != null) this.hasProfessionalExperience = hasProfessionalExperience;
StateDTO state = updatedCandidate.getState();
if(state != null) this.state = state;
CityDTO city = updatedCandidate.getCity();
if(city != null) this.city = city;
SortedSet<CandidateAcademicEducationDTO> academicEducations = updatedCandidate.getAcademicEducations();
if(academicEducations != null) EntitySetUpdater.updateEntity(this.academicEducations, academicEducations);
SortedSet<CandidateProfessionalExperienceDTO> professionalExperiences = updatedCandidate.getProfessionalExperiences();
if(professionalExperiences != null) EntitySetUpdater.updateEntity(this.professionalExperiences, professionalExperiences);
}
#Override
public Candidate toEntity() {
Candidate candidate = super.toEntity();
Set<CandidateAcademicEducation> parsedAcademicEducations = new HashSet<>();
if(academicEducations != null) {
parsedAcademicEducations.addAll(
academicEducations.stream().map(
academicEducation -> getParsedEntity(academicEducation)
).collect(Collectors.toSet())
);
}
candidate.setAcademicEducations(parsedAcademicEducations);
Set<CandidateProfessionalExperience> parsedProfessionalExperiences = new HashSet<>();
if(professionalExperiences != null) {
parsedProfessionalExperiences.addAll(
professionalExperiences.stream().map(
professionalExperience -> getParsedEntity(professionalExperience)
).collect(Collectors.toSet())
);
}
candidate.setProfessionalExperiences(parsedProfessionalExperiences);
return candidate;
}
}
Candidate professional experience:
#Entity
#Table(name = "candidate_professional_experiences")
public class CandidateProfessionalExperience {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String roleName;
private String companyName;
private String startDate;
private String endDate;
private boolean actualJob;
#Column(length = 1000)
private String assignmentsDescription;
#ManyToOne
private State state;
#ManyToOne
private City city;
#ManyToOne
private Candidate candidate;
#CreationTimestamp
#Column(updatable = false)
private Date createdAt;
#UpdateTimestamp
private Date updatedAt;
public CandidateProfessionalExperience() {
super();
}
public CandidateProfessionalExperience(
Long id, String roleName, String companyName,
String startDate, String endDate, boolean actualJob,
String assignmentsDescription, State state, City city,
Candidate candidate, Date createdAt, Date updatedAt
) {
this.id = id;
this.roleName = roleName;
this.companyName = companyName;
this.startDate = startDate;
this.endDate = endDate;
this.actualJob = actualJob;
this.assignmentsDescription = assignmentsDescription;
this.state = state;
this.city = city;
this.candidate = candidate;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
}
Candidate Professional Experience DTO:
public class CandidateProfessionalExperienceDTO extends EntityDTO<CandidateProfessionalExperience> {
private String roleName;
private String companyName;
private String startDate;
private String endDate;
private String assignmentsDescription;
private boolean actualJob;
private StateDTO state;
private CityDTO city;
#JsonProperty(access = Access.READ_ONLY)
private Date createdAt;
#JsonProperty(access = Access.READ_ONLY)
private Date updatedAt;
public CandidateProfessionalExperienceDTO() {
super();
}
public CandidateProfessionalExperienceDTO(
Long id, String roleName, String companyName, String startDate,
String endDate, String assignmentsDescription, boolean actualJob,
StateDTO state, CityDTO city, Date createdAt, Date updatedAt
) {
super(id);
this.roleName = roleName;
this.companyName = companyName;
this.startDate = startDate;
this.endDate = endDate;
this.assignmentsDescription = assignmentsDescription;
this.actualJob = actualJob;
this.state = state;
this.city = city;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
public static CandidateProfessionalExperienceDTO FromEntity(
CandidateProfessionalExperience candidateProfessionalExperienceEntity
) {
if(candidateProfessionalExperienceEntity == null) return null;
CandidateProfessionalExperienceDTO candidateProfessionalExperienceDTO = new CandidateProfessionalExperienceDTO();
candidateProfessionalExperienceDTO.setId(candidateProfessionalExperienceEntity.getId());
candidateProfessionalExperienceDTO.setRoleName(candidateProfessionalExperienceEntity.getRoleName());
candidateProfessionalExperienceDTO.setCompanyName(candidateProfessionalExperienceEntity.getCompanyName());
candidateProfessionalExperienceDTO.setStartDate(candidateProfessionalExperienceEntity.getStartDate());
candidateProfessionalExperienceDTO.setEndDate(candidateProfessionalExperienceEntity.getEndDate());
candidateProfessionalExperienceDTO.setAssignmentsDescription(
candidateProfessionalExperienceEntity.getAssignmentsDescription()
);
candidateProfessionalExperienceDTO.setActualJob(candidateProfessionalExperienceEntity.isActualJob());
candidateProfessionalExperienceDTO.setState(StateDTO.FromEntity(candidateProfessionalExperienceEntity.getState()));
candidateProfessionalExperienceDTO.setCity(CityDTO.FromEntity(candidateProfessionalExperienceEntity.getCity()));
candidateProfessionalExperienceDTO.setCreatedAt(candidateProfessionalExperienceEntity.getCreatedAt());
candidateProfessionalExperienceDTO.setUpdatedAt(candidateProfessionalExperienceEntity.getUpdatedAt());
return candidateProfessionalExperienceDTO;
}
#Override
public CandidateProfessionalExperience toEntity() {
State parsedState = getParsedEntity(state);
City parsedCity = getParsedEntity(city);
return new CandidateProfessionalExperience(
id, roleName, companyName, startDate, endDate,
actualJob, assignmentsDescription, parsedState, parsedCity,
null, null, null
);
}
#Override
public int compareTo(EntityDTO<CandidateProfessionalExperience> candidateProfessionalExperienceDTO) {
if(candidateProfessionalExperienceDTO == null) return -1;
CandidateProfessionalExperienceDTO parsedDTO = (CandidateProfessionalExperienceDTO) candidateProfessionalExperienceDTO;
int roleNameResult = StringComparator.compareStrings(roleName, parsedDTO.getRoleName());
if(roleNameResult != 0) return roleNameResult;
return StringComparator.compareStrings(companyName, parsedDTO.getCompanyName());
}
}
Candidate Academic Education:
#Entity
#Table(name = "candidate_academic_education")
public class CandidateAcademicEducation {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String institutionName;
private Integer startYear;
private Integer endYear;
private CandidateLevelOfSchooling levelOfSchooling;
#ManyToOne
private Candidate candidate;
#CreationTimestamp
#Column(updatable = false)
private Date createdAt;
#UpdateTimestamp
private Date updatedAt;
public CandidateAcademicEducation() {
super();
}
public CandidateAcademicEducation(
Long id, String title, String institutionName,
Integer startYear, Integer endYear,
CandidateLevelOfSchooling levelOfSchooling,
Candidate candidate, Date createdAt, Date updatedAt
) {
this.id = id;
this.title = title;
this.institutionName = institutionName;
this.startYear = startYear;
this.endYear = endYear;
this.levelOfSchooling = levelOfSchooling;
this.candidate = candidate;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
}
Candidate Academic Education DTO:
public class CandidateAcademicEducationDTO extends EntityDTO<CandidateAcademicEducation> {
private String title;
private String institutionName;
private Integer startYear;
private Integer endYear;
private CandidateLevelOfSchooling levelOfSchooling;
#JsonProperty(access = Access.READ_ONLY)
private Date createdAt;
#JsonProperty(access = Access.READ_ONLY)
private Date updatedAt;
public CandidateAcademicEducationDTO() {
super();
}
public CandidateAcademicEducationDTO(
Long id, String title, String institutionName,
Integer startYear, Integer endYear,
CandidateLevelOfSchooling levelOfSchooling, Date createdAt,
Date updatedAt
) {
super(id);
this.title = title;
this.institutionName = institutionName;
this.startYear = startYear;
this.endYear = endYear;
this.levelOfSchooling = levelOfSchooling;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
public static CandidateAcademicEducationDTO FromEntity(
CandidateAcademicEducation candidateAcademicEducationEntity
) {
if(candidateAcademicEducationEntity == null) return null;
CandidateAcademicEducationDTO candidateAcademicEducationDTO = new CandidateAcademicEducationDTO();
candidateAcademicEducationDTO.setId(candidateAcademicEducationEntity.getId());
candidateAcademicEducationDTO.setTitle(candidateAcademicEducationEntity.getTitle());
candidateAcademicEducationDTO.setInstitutionName(candidateAcademicEducationEntity.getInstitutionName());
candidateAcademicEducationDTO.setStartYear(candidateAcademicEducationEntity.getStartYear());
candidateAcademicEducationDTO.setEndYear(candidateAcademicEducationEntity.getEndYear());
candidateAcademicEducationDTO.setLevelOfSchooling(candidateAcademicEducationEntity.getLevelOfSchooling());
candidateAcademicEducationDTO.setCreatedAt(candidateAcademicEducationEntity.getCreatedAt());
candidateAcademicEducationDTO.setUpdatedAt(candidateAcademicEducationEntity.getUpdatedAt());
return candidateAcademicEducationDTO;
}
#Override
public CandidateAcademicEducation toEntity() {
return new CandidateAcademicEducation(
id, title, institutionName, startYear, endYear,
levelOfSchooling, null, null, null
);
}
#Override
public int compareTo(EntityDTO<CandidateAcademicEducation> candidateAcademicEducationDTO) {
if(candidateAcademicEducationDTO == null) return -1;
CandidateAcademicEducationDTO parsedDTO = (CandidateAcademicEducationDTO) candidateAcademicEducationDTO;
int titleResult = StringComparator.compareStrings(title, parsedDTO.getTitle());
if(titleResult != 0) return titleResult;
return StringComparator.compareStrings(institutionName, parsedDTO.getInstitutionName());
}
}
Candidate Services (Update method with auxiliar methods):
private void validateCandidateLinkedin(String linkedin) {
boolean existsCandidateByLinkedin = candidateRepository.existsByLinkedin(
linkedin
);
if(existsCandidateByLinkedin) {
throw new ServerException(
"A candidate with this linkedin already exists",
HttpStatus.BAD_REQUEST
);
}
}
private void validateCandidatePhoneNumber(String phoneNumber) {
boolean existsCandidateByPhoneNumber = candidateRepository.existsByPhoneNumber(
phoneNumber
);
if(existsCandidateByPhoneNumber) {
throw new ServerException(
"A candidate with this phone number already exists",
HttpStatus.BAD_REQUEST
);
}
}
private void validateNewCandidateData(
Candidate databaseCandidate, CandidateWithAllRelatedDataDTO updatedCandidate
) {
boolean hasDifferentLinkedin = StringComparator.compareStrings(
databaseCandidate.getLinkedin(), updatedCandidate.getLinkedin()
) != 0;
if(hasDifferentLinkedin) validateCandidateLinkedin(updatedCandidate.getLinkedin());
boolean hasDifferentPhoneNumber = !databaseCandidate.getPhoneNumber().equals(
updatedCandidate.getPhoneNumber()
);
if(hasDifferentPhoneNumber) validateCandidatePhoneNumber(updatedCandidate.getPhoneNumber());
}
public CandidateWithAllRelatedDataDTO update(
Long userId, CandidateWithAllRelatedDataDTO updatedCandidate
) {
Candidate findedCandidate = findOneWithAllDataByUserId(
userId
);
if(findedCandidate == null) {
throw new ServerException(
"Requested user does not have a candidate account",
HttpStatus.BAD_REQUEST
);
}
CandidateWithAllRelatedDataDTO parsedUpdatedCandidate =
CandidateWithAllRelatedDataDTO.FromEntity(findedCandidate);
parsedUpdatedCandidate.update(updatedCandidate);
validateNewCandidateData(findedCandidate, parsedUpdatedCandidate);
parsedUpdatedCandidate.setUpdatedAt(new Date());
candidateRepository.save(EntityDTO.getParsedEntity(parsedUpdatedCandidate));
return findOneById(findedCandidate.getId());
}
The JSON that i've been using both in create and update methods:
{
"photo": "photo.png",
"profession": "Programador",
"phoneNumber": "(00)9.0000-0000",
"linkedin": "https://linkedin.com.br",
"birthDate": "10/2002",
"hasProfessionalExperience": true,
"state": {
"id": 1
},
"city": {
"id": 1
},
"academicEducations": [
{
"title": "Ciência da Computação",
"institutionName": "UFERSA",
"startYear": 2020,
"endYear": 2024,
"levelOfSchooling": "INCOMPLETE_HIGHER_EDUCATION"
},
{
"title": "Direito",
"institutionName": "UERN",
"startYear": 2016,
"endYear": 2020,
"levelOfSchooling": "COMPLETE_HIGHER_EDUCATION"
}
],
"professionalExperiences": [
{
"roleName": "Administrador de negócios",
"companyName": "Unijuris",
"startDate": "05/2019",
"endDate": "08/2022",
"assignmentsDescription": "Gestão de pessoas, execução de movimentações financeiras.",
"actualJob": true,
"state": {
"id": 1
},
"city": {
"id": 1
}
},
{
"roleName": "Veterinário",
"companyName": "Nova startup",
"startDate": "05/2012",
"endDate": "06/2019",
"assignmentsDescription": "Tratamento de animais de várias espécies diferentes.",
"actualJob": false,
"state": {
"id": 1
},
"city": {
"id": 1
}
}
]
}
Based on what #Chris said on the comments, it's not possible to guarantee which prePersist/preUpdate method will be called first(From the parent entity or the child), because of that some of the related entities was working perfectly while CandidateAcademicEducation wasn't. So the solution is to set the parent (Candidate reference on CandidateAcademicEducation in this case) references before call save method from the repository.
I've also found this question talking about this uncertainty of prePersist/preUpdate/postPersist/postUpdate: PreUpdate called but child collection entity not stored
#Chris and #Deltharis Thank you very much for the help.

JPA/Hibernate - Object does not save to the database

#Service
#Transactional
#RequiredArgsConstructor
public class HTMLParser {
public static final String link1;
public static final String link2;
public final String url;
private final #NonNull VillageRepository;
public void parseLink(String link, String selektor){
// 1. úroven - získej z hlavního odkazu všechny obce nutné k proklikání
try {
Document doc = Jsoup.connect(link).get();
Elements links = doc.select(selektor);
for (Element alink : links) {
System.out.println("text: " + alink.text());
parseLink(vytvořURL(alink.attr("href")), "div.sloupec3 a");
}
if(links.isEmpty()){
links = doc.select("dl.sloupec dd");
Village village = extractInformation(links);
obecRepository.saveAndFlush(obec);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void parseLink(String link, String selektor){
try {
Document doc = Jsoup.connect(link).get();
Elements links = doc.select(selektor);
for (Element alink : links) {
parseLink(createURL(alink.attr("href")), "div.sloupec3 a");
}
if(links.isEmpty()){
links = doc.select("h4.navigace a");
Set<String> hiearchie = extractHiearchy(links);
Iterator<String> iterator = hiearchie.iterator();
links = doc.select("dl.sloupec dd");
Village village = extractInfo(links);
villageRepository.saveAndFlush(village );
}
} catch (IOException e) {
e.printStackTrace();
}
}
private Village extractInfo(Elements elements){
if(elements.size() != 13){
elements.add(3, new Element("<dd><span class=\"sede\">--- ---</span></dd>"));
}
Village village = new Village(Long.parseLong(elements.get(7).text()), elements.get(0).text(), elements.get(1).text(),
elements.get(2).text(), elements.get(3).text(), elements.get(5).text(), elements.get(6).text(),
elements.get(8).text(), getHours(elements.last()));
village.setEmails(extrahjZBloku(elements.get(9)));
village.setWWW(extrahjZBloku(elements.get(10)));
village.setPhones(extrahujTelefony(elements.get(11)));
village.setAccounts(extrahujÚčetAIBAN(elements.get(4)));
return village;
}
#Entity
#Getter
#Setter
public class Village {
public Village (){}
#Id
private long code;
#Column
private String type;
#Column(name = "name")
private String name;
#Column
private String adress;
#Column(name = "sec_adress")
private String secAdress;
#Column(name = "bank")
private String bank1;
#Column(name = "bankovní_spojení2")
private String bank2;
#Column
private String IBAN1;
#Column
private String IBAN2;
#Column
private String IC;
#Column
private String DIC;
#Column
private String shortcut;
#Column
private String email1;
#Column
private String email2;
#Column
private String email3;
#Column
private String email4;
#Column
private String www1;
#Column
private String www2;
#Column
private String www3;
#Column
private String www4;
#Column
private String telefon1;
#Column
private String telefon2;
#Column
private String telefon3;
#Column
private String telefon4;
#Lob
#Column(name = "hours")
private String hours;
}
public interface VillageRepository extends JpaRepository<Village, Long> {
}
My problem is that object village in the method parseLink does not save to the database... nothing happens and not even error shows up... When I try to save that object in the main method with with test parameters, it works, but not where I need... When I try to save something different in that method, nothing also happens, so the problem must be in the method parseHTML i guess
Thanks for help
PS: In intelij, i can see created insert command which seems to OK, but nothing is in the database...
Try putting the #Transactional annotation on the public functions, instead of the class.
I do not know how you really distributed into classes, but is it your JpaRepository decorated with the annotation #Repository ??

PostgreSQL not doing autoincrement

I am using postgresql with springboot. So whenever I am using post method to add a new detail in my table instead of autoincrementing id it's going from 1 to 3. It's taking alternate values rather than consecutive values. I have given following properties and then created table:
spring.jpa.hibernate.ddl-auto=create
Didn't create the table manually. What is the reason for this error? This is my entity class.
#Entity
#Table(name = "NORTHBOUND_SUBSCRIPTION")
public class NBSubscription {
#Id
#GeneratedValue
#Column(name = "nb_id")
private Long nbId;
#Column(name = "DEVICE_FILTER")
private String deviceFilter;
#Column(name = "INTERFACE_FILTER")
private String interfaceFilter;
#ManyToOne
#JoinColumn(name="subscriber_id", referencedColumnName="SUBSCRIBER_ID")
private Subscriber subscriber;
#OneToOne
#JoinColumn(name="sensor_group_id", referencedColumnName="ID")
private SensorGroup sensorGroup;
#Column(name = "EVENT_TYPE")
private String eventType;
#Column(name = "SAMPLING_INTERVAL")
private Integer samplingInterval;
#Column(name = "CREATEAT")
#DateTimeFormat(pattern = "dd-MM-yyyy HH:mm")
private Timestamp createAt;
#Column(name = "MODIFIEDAT")
#DateTimeFormat(pattern = "dd-MM-yyyy HH:mm")
private Timestamp modifiedAt;
#Column(name = "CREATEDBY")
private String createdBy;
#Column(name = "MODIFIEDBY")
private String modifiedBy;
#Column(name = "mark_deletion")
private String markDeletion;
public NBSubscription() {
super();
}
public NBSubscription(Subscriber subscriber, SensorGroup sensorGroup) {
super();
this.subscriber = subscriber;
this.sensorGroup = sensorGroup;
}
public Long getNbId() {
return nbId;
}
public void setNbId(Long nbId) {
this.nbId = nbId;
}
public String getDeviceFilter() {
return deviceFilter;
}
public void setDeviceFilter(String deviceFilter) {
this.deviceFilter = deviceFilter;
}
public String getInterfaceFilter() {
return interfaceFilter;
}
public void setInterfaceFilter(String interfaceFilter) {
this.interfaceFilter = interfaceFilter;
}
#JsonIgnore
public Subscriber getSubscriber() {
return subscriber;
}
public void setSubscriber(Subscriber subscriber) {
this.subscriber = subscriber;
}
public SensorGroup getSensorGroup() {
return sensorGroup;
}
public void setSensorGroup(SensorGroup sensorGroup) {
this.sensorGroup = sensorGroup;
}
public Integer getSamplingInterval() {
return samplingInterval;
}
public void setSamplingInterval(Integer samplingInterval) {
this.samplingInterval = samplingInterval;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public Timestamp getCreateAt() {
return createAt;
}
public void setCreateAt(Timestamp createAt) {
this.createAt = createAt;
}
public Timestamp getModifiedAt() {
return modifiedAt;
}
public void setModifiedAt(Timestamp modifiedAt) {
this.modifiedAt = modifiedAt;
}
public String getMarkDeletion() {
return markDeletion;
}
public void setMarkDeletion(String markDeletion) {
this.markDeletion = markDeletion;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}
Try this
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
if it doesn't work, try using the table sequence
#Id
#GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ")
Your autoincrement is implemented with a sequence, and by default entities share the same sequence, so the autoincrement values get spread across the entities.
You could assign each entity its own sequence. But be aware sequences don't participate in transactions. That means if you have a rollback there will be a break in the numbering. Occasional gaps are not avoidable.
If you are making this sequence visible to users and they expect the numbering to be contiguous, my advice is to not use a sequence for that, and keep the user-visible counter in a field separate from the id. If it is visible to users, then at some point it will need to change, and you can't change ids.

Two Representations of the Same Object - Hibernate Issue

I have a select statement that loads in the class Folders with a one-to-many relationship with File. While this sometimes happens without error, it sometimes gives me a Hibernate error saying that my use of session is unsafe, or that there were two representations of the same collection Folders.file. What am I doing wrong? Thanks for your help!
Folders.java
#Entity
#Table(name= "folders")
public class Folders implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name = "folder_code")
private Integer folderCode;
#Column(name = "assign_code")
private Integer assignCode;
public Set<File> getFile() {
return file;
}
public void setFile(Set<file> assignments) {
this.file = file;
}
#OneToMany(targetEntity=File.class,cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#JoinColumn(name="assign_code",referencedColumnName="assign_code")
Set<Folder> folder;
public Integer getAssignCode() {
return assignCode;
}
public void setAssignCode(Integer assignCode) {
this.assignCode = assignCode;
}
public Integer getFolderCode() {
return folderCode;
}
public void setFolderCode(Integer folderCode) {
this.folderCode = folderCode;
}
public Date retrieveFileStartDate(){
List<File> file;
if(this.getFile()!=null){
file= new ArrayList<File>(this.getFile());
}else{
file = new ArrayList<File>();
}
return file.size()>0 ? new
Date(file.get(0).getStartDate()): null;
}
}
File.java
#Entity
#Table(name= "file")
public class File implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name = "assign_code")
private Integer assignCode;
#Column(name = "start_date")
private String startDate;
#Column(name = "end_date")
private String endDate;
public Integer getAssignCode() {
return assignCode;
}
public void setAssignCode(Integer assignCode) {
this.assignCode = assignCode;
}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
}
I am not sure about the error you are getting but looking at your entities i can say that relationship mapping is not correct.
You are mapping #OneToMany in Folder entity but what about #ManyToOne in File entity?
also define mappedBy attribute to make it work expected.
Folder.java
#OneToMany(targetEntity=File.class,cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="file")
#JoinColumn(name="assign_code",referencedColumnName="assign_code")
private Set<Folder> folder;
File.java
#ManyToOne
private File file;
//getter and setter

Convert json array of arrays to some Java representation using Jackson

I am trying to convert following jsonString structure to a Java list/array of objects:
[
[1,21940000,1905386136,null,"KR","akshay","04/06/2017","03/06/2017",2017,9,40,"JPY",7478,"JPY",7478,"WHT (Residen",null,0,"03/06/2017","03/06/2017","20170604",null],
[2,21940000,1903732187,null,"KR",null,"06/06/2017","05/06/2017",2017,9,40,"JPY",608547485,"JPY",608547485,"WHT (Non-Resi",null,0,"05/06/2017","05/06/2017","20170606",null],
[3,21940000,2001898163, ............... ]
.
.
.
.
.
.
.
.
]
Below is Java code:
ObjectMapper mapper = new ObjectMapper();
MyData[][] data = mapper.readValue(jsonString, MyData[][].class);
But, I get following error:
com.fasterxml.jackson.databind.JsonMappingException:
Can not construct instance of com.org.model.MyData:
no String-argument constructor/factory method to deserialize from String value ('KR')
at [Source: java.io.StringReader#1327cf05; line: 1, column: 30] (through reference chain: java.lang.Object[][0]->java.lang.Object[][4])
Can someone help me out please? Thanks
EDIT: Below is my POJO MyData.java code:
#Entity
#Table(schema = "My_Schema", name = "My_Data_Table")
#SuppressFBWarnings(value = { "EI_EXPOSE_REP", "EI_EXPOSE_REP2" }, justification = "I prefer to suppress these FindBugs warnings")
public class MyData implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6936461726389768288L;
public MyData() {
super();
}
/**
* #param id
*/
public MyData(Long id) {
super();
this.id = id;
}
#Id
private Long id;
#Column(name = "ACCOUNT")
private long account;
#Column(name = "DOC_NUMBER")
private long docNumber;
#Column(name = "TYPE")
private String type;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
#Column(name = "DOC_DATE")
private Date docDate;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
#Column(name = "POSTING_DATE")
private Date postingDate;
#Column(name = "YEAR")
private long year;
#Column(name = "PERIOD")
private long period;
#Column(name = "PK")
private long pk;
#Column(name = "TAX_CODE")
private String taxCode;
#Column(name = "CCY")
private String ccy;
#Column(name = "DOC_CCY_AMT")
private long docCcyAmt;
#Column(name = "LOCAL_CCY")
private String localCcy;
#Column(name = "LOCAL_CCY_AMT")
private long localCcyAmt;
#Column(name = "TEXT")
private String text;
#Column(name = "DOC_HEADER_TEXT")
private String docHeaderText;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
#Column(name = "CLEARING_DATE")
private Date clearingDate;
#Column(name = "CLEARING_DOC")
private long clearingDoc;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
#Column(name = "ENTRY_DATE")
private Date entryDate;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
#Column(name = "VALUE_DATE")
private Date valueDate;
#Column(name = "ASSIGNMENT")
private String assignment;
#Column(name = "REMARKS")
private String remarks;
// Getters and setters to follow .....
So, the thing is my input JSON string is an array of arrays and I want it to be in some Java representation be it an ArrayList or plain Array...
You are probably missing required attributes for "KR" in your "MyData" class. Until you post definition for MyData class here, take a look at this code. It will surely help you.
class Student {
private String name;
private int age;
public Student(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "Student [ name: "+name+", age: "+ age+ " ]";
}
}
and to test it
import java.io.IOException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
public class JacksonTester {
public static void main(String args[]){
ObjectMapper mapper = new ObjectMapper();
String jsonString = "{\"name\":\"Mahesh\", \"age\":21}";
//map json to student
try{
Student student = mapper.readValue(jsonString, Student.class);
System.out.println(student);
mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
jsonString = mapper.writeValueAsString(student);
System.out.println(jsonString);
}
catch (JsonParseException e) { e.printStackTrace();}
catch (JsonMappingException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
}
}

Categories

Resources