Casting to Polygon java Spring JPA - java

I have a postgres db with a column that has polygon type. When I try to save something in this table i get the following error:
org.postgresql.util.PSQLException: ERROR: column "polygon" is of type polygon but expression is of type bytea
Hint: You will need to rewrite or cast the expression.
How do I cast this?
This is the class that represents the table
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.annotations.Type;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
import org.springframework.validation.annotation.Validated;
import javax.persistence.*;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
#Validated
#Entity
#Table(name="boundary", schema = "public")
#JsonIgnoreProperties(value = "id")
#javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2019-03-09T16:35:39.240Z[GMT]")
public class Boundary {
#Id
#Column(name = "boundary_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigDecimal id;
#Column(name = "polygon")
private Polygon polygon;
#OneToOne
#JoinColumn(name="field_id")
private FieldResource field;

Related

JPA Spring repository findAll() returns an empty List

I am trying to fetch all the records using JPA findAll. If I run the same query in the terminal, I get some rows as a result, but not through JPA. I tried other answers on stackoverflow, but nothing worked. I tried adding public getters and setters, although which I assume was done by the annotations.
Model class:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#ToString
#Entity
#Table(name = "tea")
public class Product {
#Id
#GeneratedValue(generator = "prod_seq", strategy = GenerationType.SEQUENCE)
#SequenceGenerator(name = "prod_seq", sequenceName = "seq_prod", allocationSize = 1, initialValue = 1)
#Column(name = "product_id")
private int productId;
private String name;
#Column(name = "price_per_kg")
private int pricePerKg;
private String type;
#Lob
#Column(length = 2000)
private String description;
#Column(name = "image_url")
private String imageUrl;
private String category;
}
Service class:
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tea.exceptions.ProductNotFoundException;
import com.tea.models.Product;
import com.tea.repository.ProductRepository;
#Service
public class ProductServiceImpl implements ProductService{
#Autowired
ProductRepository productRepository;
#Override
public List<Product> getAll() throws ProductNotFoundException {
return productRepository.findAll();
}
}
Edit: Adding the repository code:
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.tea.models.Product;
public interface ProductRepository extends JpaRepository<Product,Integer >{
#Query("from Product where type like :type ")
List<Product> findByType( String type);
#Query("from Product where type =?2 and category= ?1")
List<Product> findByCategoryAndType(String category, String type);
#Query("from Product where category like :category")
List<Product> findByCategory(String category);
}
I think query should contain alias name for table like Product p and then condition like p.type.

Stored Procedure Join Entities Hibernate/Spring Data

I got those two tables:
table z_users:
id
name
table z_phones:
id
iduser
phone
I got a stored procedure with this query too:
Select * from z_users INNER JOIN z_phones on z_users.id = z_phones.iduser where z_users.id = 1;
I would like to fetch this stored proc via Spring Data/Hibernate.
So i created two classes:
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Immutable;
import javax.persistence.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
#Data
#Entity
#Immutable
#NoArgsConstructor
public class ZUser {
#Id
private int id;
private String name;
public ZUser(String name, ZPhone... zPhones) {
this.name = name;
this.zPhone.addAll(Arrays.stream(zPhones).collect(Collectors.toUnmodifiableList()));
}
#OneToMany
private List<ZPhone> zPhone;
}
import lombok.Data;
import org.hibernate.annotations.Immutable;
import javax.persistence.Entity;
import javax.persistence.Id;
#Data
#Entity
#Immutable
public class ZPhone {
#Id
private int id;
private String phone;
}
I tried to call the SP with this code:
import lombok.extern.slf4j.Slf4j;
import net.resourcestorage.demojoin.database.model.ZUser;
import org.hibernate.Session;
import org.springframework.stereotype.Service;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;
#Slf4j
#Service
public class ZUserService {
#PersistenceContext
private EntityManager entityManager;
public List<ZUser> getUsers() {
Session session = (Session) entityManager.getDelegate();
Query query = session.createSQLQuery("CALL getUsers()").addEntity(ZUser.class);
log.info(query.getResultList().toString());
List list = query.getResultList();
return null; // don't care about this
}
}
Running this, Hibernate does this:
Hibernate: CALL getUsers()
Hibernate: select zphone0_.ZUser_id as zuser_id1_4_0_, zphone0_.zPhone_id as zphone_i2_4_0_, zphone1_.id as id1_2_1_, zphone1_.phone as phone2_2_1_ from ZUser_ZPhone zphone0_ inner join ZPhone zphone1_ on zphone0_.zPhone_id=zphone1_.id where zphone0_.ZUser_id=?
Here, hibernate should not do the select.
I start to think that I'm not following the best way, which could be the best way to achieve my goal?
Thanks!

Strange and duplicated UUIDs are getting generated all the time

There is an reccuring issue with my Spring Boot application (using Oracle Java 8, Hibernate and Oracle DB).
I have following error in the logs:
WARN o.h.e.jdbc.spi.SqlExceptionHelper.logExceptions - SQL Error: 1, SQLState: 23000
ERROR o.h.e.jdbc.spi.SqlExceptionHelper.logExceptions - ORA-00001: unique constraint (MY_SCHEMA.SYS_C0057302) violated
This constraint (SYS_C0057302) is UUID being UNIQUE. (UUID VARCHAR2(32) NOT NULL UNIQUE)
I cannot provoke this behaviour running it locally (even with load tests) - locally on windows it looks fine, but on RHEL (where it is deployed) problem occurs all the time.
Note that I have dozen more entity classes which all have UUIDs, but only this class is generating such strange duplicates all the time.
No idea how to fix it. Cannot find root cause of this.
Examples of UUIDsand classes used below:
There is a bit of normal UUIDs at the start, but after some time strange and duplicated UUIDs are being created. On 2 different RHEL envs.
Examples of normal UUIDs:
0C34561DD75D422CAD652715DF6C6E75
0CB86A03945040B9886752CC07EB116E
0DAA1A3AF2B5438F8CB9489348A92223
0EAE079E621B4D2B8E8BE445F76B14C9
0FCF05797E7E40DE8D3A9D6A3B44AAE1
12DEBCAB53C94285A4C3FF32C5A0BF8E
132A877F404D44069F78D9B74DD4BDC9
1338A8CE09B14552B78CBAD640A3CF29
136310C44374412FB5B1B8FAF7E35330
Example of strange UUIDs generated by UUID.randomUUID() - 99% of UUIDs are like that, very similiar, with 3 as number that comes up a lot:
33333330333433363333333233333339
33333330333433363333333333333336
33333330333433363333333433333330
33333330333433363333333433333332
33333330333433363333333433333333
33333330333433363333333533333330
33333330333433363333333533333333
33333330333433363333333533333339
33333330333433363333333533343332
33333330333433363333333633333332
33333330333433363333333633333334
33333330333433363333333733333333
33333330333433363333333733343335
33333330333433363333333833333333
33333330333433363333333933333332
TaskEntity class:
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import ----DashboardTaskDto;
import ----SimpleUserDto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;
#Getter
#Setter
#NoArgsConstructor
#Entity
#Table(name = "TASK")
#ToString
#EntityListeners(AuditingEntityListener.class)
#Slf4j
class TaskEntity {
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TASK_SEQ")
#SequenceGenerator(sequenceName = "TASK_SEQ", allocationSize = 1, name = "TASK_SEQ")
#Id
private Long id;
#Column(name = "KKF")
private String kkf;
#EqualsAndHashCode.Include
private UUID uuid = UUID.randomUUID();
private String customerName;
private String assignedUserName;
private String assignedUserRole;
private int dpd;
private Boolean bgk;
private String courtProceedings;
private String name;
private LocalDateTime dueDate;
private LocalDateTime doneDate;
private BigDecimal totalLiabilities;
private Long issueActivityId;
private String userId;
#Enumerated(EnumType.STRING)
private TaskStatus status;
#CreatedDate
private LocalDateTime created;
#LastModifiedDate
private LocalDateTime modified;
#Builder
public TaskEntity(String kkf, String customerName, String assignedUserName, String assignedUserRole, int dpd, Boolean bgk, String courtProceedings, String name, LocalDateTime dueDate, LocalDateTime doneDate, BigDecimal totalLiabilities, Long issueActivityId, String userId, TaskStatus status, LocalDateTime created, LocalDateTime modified) {
this.kkf = kkf;
this.customerName = customerName;
this.assignedUserName = assignedUserName;
this.assignedUserRole = assignedUserRole;
this.dpd = dpd;
this.bgk = bgk;
this.courtProceedings = courtProceedings;
this.name = name;
this.dueDate = dueDate;
this.doneDate = doneDate;
this.totalLiabilities = totalLiabilities;
this.issueActivityId = issueActivityId;
this.userId = userId;
this.status = status;
this.created = created;
this.modified = modified;
}
Task repository class:
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.repository.Repository;
import org.springframework.lang.Nullable;
import java.util.Optional;
interface TaskRepository extends Repository<TaskEntity, Long> {
TaskEntity save(TaskEntity from);
Optional<TaskEntity> findByIssueActivityId(Long id);
Page<TaskEntity> findAll(#Nullable Specification<TaskEntity> spec, Pageable pageable);
}
TaskCreator used for entity creation/updates:
class TaskCreator {
public TaskEntity from(IssueActivityEntity issueActivityEntity) {
IssueEntity issue = issueActivityEntity.getIssue();
CustomerEntity customer = issue.getCustomer();
UserEntity user = issueActivityEntity.getUser();
return TaskEntity.builder()
.kkf(customer.getKkf())
.customerName(customer.getCompanyName())
.assignedUserName(user.getName())
.assignedUserRole(user.getRole())
.dpd(issue.retrieveMaxDpd())
.bgk(customer.isBgk())
.courtProceedings(customer.getCourtProceedings())
.name(issueActivityEntity.getActivity().getStatus())
.dueDate(issueActivityEntity.getDueDate())
.doneDate(issueActivityEntity.getDoneDate())
.totalLiabilities(customer.getTotalLiabilities())
.issueActivityId(issueActivityEntity.getId())
.status(issueActivityEntity.getStatus())
.userId(user.getId())
.build();
}
TaskEntity updateFrom(final TaskEntity task, final IssueActivityEntity ia) {
IssueEntity issue = ia.getIssue();
CustomerEntity customer = issue.getCustomer();
UserEntity user = ia.getUser();
task.setKkf(customer.getKkf());
task.setCustomerName(customer.getCompanyName());
task.setAssignedUserRole(user.getRole());
task.setDpd(issue.retrieveMaxDpd());
task.setBgk(customer.isBgk());
task.setCourtProceedings(customer.getCourtProceedings());
task.setName(ia.getActivity().getStatus());
task.setDueDate(ia.getDueDate());
task.setDoneDate(ia.getDoneDate());
task.setTotalLiabilities(customer.getTotalLiabilities());
task.setIssueActivityId(ia.getId());
task.setStatus(ia.getStatus());
task.setUserId(user.getId());
return task;
}
}
Update 1:
I tried setting -Djava.security.egd=file:/dev/./urandom but this did not help at all.

JpaRepository with complex key class is failing validation with error "Validation failed for query for method" when using JPA syntax

I am trying to use the "out of the box" goodies of JPA and get data from DB to an object. It is working perfect when the JpaRepository is using a simple class as key, but for test cases when the key class is a bit complex, the jpa validation fails even for the simplest queries.
using a native_query=true will solve the issue, however I am not sure what I am doing wrong and what am I missing.
MyTestPK.java:
package com.mytest.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Embeddable;
import java.io.Serializable;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Embeddable
public class MyTestPK implements Serializable {
private String type;
private String name;
}
MyTest.java:
package com.mytest.model;
import lombok.Data;
import javax.persistence.*;
#Entity
#Table(name = "my_test")
#Data
#IdClass(MyTestPK.class)
public class MyTest {
#Id
#Column(name = "my_test_type", nullable = false)
private String type;
#Id
#Column(name = "my_test_name", nullable = false)
private String name;
#Column(name = "my_test_misc")
private String misc;
}
MyTestRepository.java:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
#Repository
public interface MyTestRepository extends JpaRepository<MyTest, MyTestPK> {
#Query(value="SELECT m FROM MyTest m")
List<MyTest> getAllObjs();
}
Getting the following error:
....
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List
com.mytest.dao.MyTestRepository.getAllObjs()!
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
You can use #EmbeddedId and no need to define columns in the entity classes again.
MyTestPK.java:
package com.mytest.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Embeddable;
import java.io.Serializable;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Embeddable
public class MyTestPK implements Serializable {
#Column(name = "my_test_type", nullable = false)
private String type;
#Column(name = "my_test_name", nullable = false)
private String name;
}
MyTest.java:
package com.mytest.model;
import lombok.Data;
import javax.persistence.*;
#Entity
#Table(name = "my_test")
#Data
public class MyTest {
#EmbeddedId
private MyTestPK pk;
#Column(name = "my_test_misc")
private String misc;
}

jpa #manytoone creates composite primary key instead of #id

I am running spring jpa project and I have following class containing #ManyToOne relations:
package ba.fit.vms.pojo;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import org.springframework.format.annotation.DateTimeFormat;
#Entity
#Table(name="korisnik_vozilo")
public class KorisnikVozilo implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private Long id;
#ManyToOne( cascade = {CascadeType.REFRESH}, fetch=FetchType.EAGER )
#JoinColumn(nullable=false, updatable=false)
private Vozilo vozilo;
#ManyToOne( cascade = {CascadeType.REFRESH}, fetch=FetchType.EAGER )
#JoinColumn(nullable=false, updatable=false)
private Korisnik korisnik;
#Column(name = "dodijeljeno")
#DateTimeFormat(pattern = "yyyy-MM-dd")
#NotNull
private Date dodijeljeno;
#Column(name = "vraceno")
#DateTimeFormat(pattern = "yyyy-MM-dd")
private Date vraceno;
...
}
For some reason, starting the server, this code creates composite primary key (korisnik_id,vozilo_vin), instead of #Id defined primary key. Here is the screenshot of the table:
Can someone explain to me what did I do wrong and how to write this code so I do not get this composite key in the database, but the one defined in the class.
It even sets autoincrement on korisnik_id!
Try getting rid of updatable=false. being unupdatable, the two columns might be be viewed as an immutable identity of the entity.
You may check how you can use #JoinColumn to solve your problem.

Categories

Resources