UUID Mapping in hibernate - spring

I have mapped a table to my table and trying to add some values in it. but I am getting errors as below
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'create, delete, read, role_id, update, id) values
(_binary'ØN_WlAs—\niÊnÙ' at line 1
my entities are
RoleSettings.java
#Entity #Table(name = "role_settings")
#Getter #Setter #Data
public class RoleSettings implements Serializable {
private static final long serialVersionUID = 8862104773442047690L;
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
#ManyToOne
#JoinColumn(name = "role_id", referencedColumnName = "id", foreignKey = #ForeignKey(name = "role_settings_iam_role_FK"))
private RoleMaster roleId;
}
RoleMaster.java
#Entity #Table(name = "role")
#Getter #Setter #Data
public class RoleMaster implements Serializable {
private static final long serialVersionUID = 1792968151371176640L;
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
#Column(name = "name", nullable = false, length = 255)
private String name;
}
RoleSettingsRepository.java
public interface RoleSettingsRepository extends JpaRepository<RoleSettings, UUID>{}
RoleSettingsService.java
#Service
Class RoleSettingsService {
#Autowired
private RoleSettingsRepository roleSettingsRepository;
public BaseDTO create(RoleSettings roleSettings) {
BaseDTO response = new BaseDTO();
RoleSettings newRoleSettings = new RoleSettings();
try {
newRoleSettings.setRoleId(roleSettings.getRoleId());
newRoleSettings.setAppAccessId(roleSettings.getAppAccessId());
newRoleSettings.setCreate(roleSettings.getCreate());
newRoleSettings.setUpdate(roleSettings.getUpdate());
newRoleSettings.setRead(roleSettings.getRead());
newRoleSettings.setDelete(roleSettings.getDelete());
roleSettingsRepository.save(newRoleSettings);
response.setStatusCode(200);
} catch (Exception e) {
}
return response;
}
}
RoleSettingsController.java
#RestController
#RequestMapping("/v1/rolesettings")
public class RoleSettingsController {
#Autowired
private RoleSettingsService roleSettingsService;
#PostMapping("/post")
public BaseDTO create(#RequestBody RoleSettings roleSettings) {
BaseDTO response = roleSettingsService.create(roleSettings);
return response;
}
}
my json object
{ "roleId" :{"id": "b2e64c82-ab75-41d3-bb10-e9150f314807"} }
and my roleId is stored in database as type binary(16).

Check in your database data type of the id column. It has to be BINARY(16). And annotate your entity field as:
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
#Column(columnDefinition = "BINARY(16)")
private UUID id;
Note that you nned to add a column definition in this case.

Related

Sending file and JSON in a many-to-many relationship

I have a model called EPI that has a many to many relationship with Model Images, I am not able to do the #PostMapping for this object.
see my code
EPI Entity:
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Table(name = "EPI")
public class EPI implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "Id_EPI")
private UUID id;
#Column(name = "Nome", nullable = false, length = 100)
private String nome;
#Column(name = "Marca", nullable = false, length = 100)
private String marca;
#Column(name = "CA", nullable = false, length = 100)
private String ca;
#Column(name = "Descricao", nullable = false)
private String descricao;
#Column(name = "Foto")
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "epi_images",
joinColumns = {
#JoinColumn(name = "epi_id")
},
inverseJoinColumns = {
#JoinColumn(name = "image_id")
})
private Set<ImageModel> foto;
#Column(name = "Quantidade", nullable = false)
private Integer quantidade;
}
Image Entity:
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Table(name = "image_model")
public class ImageModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
private String name;
#Column(name = "type")
private String type;
#Column(name = "image_data", unique = false, nullable = false, length = 100000)
private byte[] imageData;
}
Controller EPI:
#PostMapping("/addNewEPI")
public ResponseEntity<Object> salvarFEPI(#RequestPart("image")MultipartFile file,
#RequestPart("epiModel") EPI epi) throws IOException {
try {
ImageModel foto = productImageService.uploadImage(file);
epi.setFoto((Set<ImageModel>) foto);
return ResponseEntity.status(HttpStatus.CREATED).body(epiService.save(epi));
} catch (Exception e){
System.out.println(e.getMessage());
return null;
}
Service Image:
public ImageModel uploadImage(MultipartFile file) throws IOException {
ImageModel image = new ImageModel();
image.setName(file.getOriginalFilename());
image.setType(file.getContentType());
image.setImageData(ImageUtility.compressImage(file.getBytes()));
return image;
}
As I am passing the parameters in Postman:
enter image description here
Return from Spring Boot:
enter image description here
If anyone can help me I would be very grateful!
I tried passing the parameters in different ways. I just want it to populate my tables passing the parameters of the EPI entity and the Image file.
enter image description here

Spring Data Projection with OneToMany error

I have a entity call Circuit.
#Entity
public class Circuit implements Comparable<Circuit>, Serializable {
#Column
private String id;
#OneToMany(mappedBy = "circuit", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
private Set<Step> workflow = new HashSet<>();
...
}
I have a class called CircuitLight
public class CircuitLight {
private String id;
private Set<Step> workflow;
/* constructor, getters and setters */
}
In my CircuitRepository, i'm trying to make a projection
#Transactional(readOnly = true)
#Query("select new com.docapost.circuit.CircuitLight(c.id, c.workflow) from Circuit c where c.account.siren = :siren")
Set<CircuitLight> findAllByAccountSirenProjection(#Param("siren") String siren);
When i execute, i have a error message:
could not extract ResultSet; SQL [n/a] com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'circuit0_.id' in 'on clause'
I try with other entity. Every time i have a property with a relation #OneToMany, i have the issue...
Is it possible to make a projection with class (Without use a interface) when there are a relation OneToMany ?
UPDATE:
Step.class
#Entity
public class Step implements Comparable<Step>, Serializable {
private static final List<String> INDEXABLE_PROCESSES = Arrays.asList(
ParapheurWorkflowModel.SERVER,
ParapheurWorkflowModel.SIGN,
ParapheurWorkflowModel.VISA
);
#Id
#GeneratedValue
#Expose
#SerializedName("step_id")
public long id;
#ManyToOne
public Circuit circuit;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(joinColumns = #JoinColumn(name = "step_id"), inverseJoinColumns = #JoinColumn(name = "technicalGroup_id"))
private List<TechnicalGroup> technicalGroups = new ArrayList<>();
#Column(name = "step_type", nullable = false)
#Expose
#SerializedName("subprocess_ref")
public String type;
#Column(nullable = false)
public int orderIndex;
/* contructor, getters and setters */
}
UPDATE 2:
Hum.... My bad, in my circuit class, i have a EmbeddedId
#EmbeddedId
private CircuitPK key;
#Embeddable
public static class CircuitPK implements Serializable {
public String id;
public String siren;
}
I try with this code in Step.class
#ManyToOne
#JoinColumns(value = {
#JoinColumn(name = "circuit_siren", referencedColumnName = "siren"),
#JoinColumn(name = "circuit_id", referencedColumnName = "id")
})
public Circuit circuit;
The result is the same
Write the following code in the Step entity
#ManyToOne
#JoinColumn(name="id", nullable=false)
private Circuit circuit;

OneToOne CascadeType in spring data jpa

I use OneToOne in the spring data JPA and I want to delete a record from the Address table without touching the user. But I can't.
If I remove User, in this case Address is removed, that's good.
But how can you delete an Address without touching the User?
https://github.com/myTestPercon/TestCascade
User.Java
#Entity
#Table(name = "user", schema = "testCascade")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Address address;
// Getter and Setter ...
}
Address.java
#Entity
#Table(name = "address", schema = "testCascade")
public class Address implements Serializable {
#Id
private Long id;
#Column(name = "city")
private String city;
#OneToOne
#MapsId
#JoinColumn(name = "id")
private User user;
// Getter and Setter ...
}
DeleteController.java
#Controller
public class DeleteController {
#Autowired
ServiceJpa serviceJpa;
#GetMapping(value = "/deleteAddressById")
public String deleteAddressById () {
serviceJpa.deleteAddressById(4L);
return "redirect:/home";
}
}
You got your mapping wrong thats all is the problem .
try the below and see
User.java
#Entity
#Table(name = "user", schema = "testCascade")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToOne(cascade=CascadeType.ALL)
#JoinColumn(name="foriegn key column in user table for address example.. address_id")
private Address address;
// Getter and Setter ...
}
Address.java
#Entity
#Table(name = "address", schema = "testCascade")
public class Address implements Serializable {
#Id
private Long id;
#Column(name = "city")
private String city;
//name of the address variable in your user class
#OneToOne(mappedBy="address",
cascade={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH})
private User user;
// Getter and Setter ...
}
In order to solve this problem, you need to read the hibernate Documentation Hibernate Example 162, Example 163, Example 164.
And also I recommend to look at this is Using #PrimaryKeyJoinColumn annotation in spring data jpa
This helped me in solving this problem.
And also you need to specify the parameter orphanRemoval = true
User.java
#Entity(name = "User")
#Table(name = "user", schema = "testother")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Address address;
public void addAddress(Address address) {
address.setUser( this );
this.address = address;
}
public void removeAddress() {
if ( address != null ) {
address.setUser( null );
this.address = null;
}
}
// Getter and Setter
}
Address.java
#Entity(name = "Address")
#Table(name = "address", schema = "testother")
public class Address implements Serializable {
#Id
private Long id;
#Column(name = "city")
private String city;
#OneToOne
#MapsId
#JoinColumn(name = "id")
private User user;
// Getter and Setter
}
DeleteController .java
#Controller
public class DeleteController {
#Autowired
ServiceJpa serviceJpa;
#GetMapping(value = "/deleteUser")
public String deleteUser () {
User user = serviceJpa.findUserById(2L).get();
user.removeAddress();
serviceJpa.saveUser(user);
return "/deleteUser";
}
}
Or make a custom SQL query.
#Repository
public interface DeleteAddress extends JpaRepository<Address, Long> {
#Modifying
#Query("delete from Address b where b.id=:id")
void deleteBooks(#Param("id") Long id);
}
public class Address {
#Id
private Long id;
#MapsId
#JoinColumn(name = "id")
private User user;
}
Rename #JoinColumn(name = "id") to #JoinColumn(name = "user_id")
You can't say that the column that will point to user will be the id of the Address

JPA Specification filtering nested object

I am trying to fetch nested object property but getting illegalArgument exception.
AuditTestingPlanSpecification name = new AuditTestingPlanSpecification(new SearchCriteria("auditPlanId.auditPlanEntity", ":",dates));
Page<AuditTestingPlanMaster> a = auditTestingPlanMasterRepository.findAll(name, ten);
Please find below code,
public class AuditTestingPlanSpecification implements Specification<AuditTestingPlanMaster> {
private SearchCriteria criteria;
public AuditTestingPlanSpecification(SearchCriteria searchCriteria) {
this.criteria = searchCriteria;
}
#Override
public Predicate toPredicate(Root<AuditTestingPlanMaster> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
if (root.get(criteria.getKey()).getJavaType() == String.class) {
return builder.like(root.<String>get(criteria.getKey()), "%" + criteria.getValue().get(0).toString() + "%");
} else {
return builder.equal(root.get(criteria.getKey()), criteria.getValue().get(0).toString());
}
return null;
}
}
Class SearchCriteria.java
public class SearchCriteria {
public SearchCriteria(String key, String operation, List<Object> value) {
super();
this.key = key;
this.operation = operation;
this.value = value;
}
private String key;
private String operation;
private List<Object> value;
// getters & setters
}
Class AuditTestingPlanMaster.java
#Entity
#Table(name = "audit_testing_plan_master")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class AuditTestingPlanMaster implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#Column(name = "risk_area_id")
private Long riskAreaId;
#Column(name = "expected_revert_date")
private Instant expectedRevertDate;
#Column(name = "created_date")
private Instant createdDate;
#Column(name = "last_modified_date")
private Instant lastModifiedDate;
#JoinColumn(name = "audit_plan_id", referencedColumnName = "id")
private AuditPlanMaster auditPlanId;
//getters & setters
}
Class AuditPlanMaster.java
#Entity
#Table(name = "audit_plan_master")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class AuditPlanMaster implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#Column(name = "remarks", length = 255)
private String remarks;
#Column(name = "audit_plan_entity", length = 50)
private String auditPlanEntity;
#Column(name = "start_date")
private Instant startDate;
#Column(name = "end_date")
private Instant endDate;
//getters & setters
}
I want to fetch all the AuditTestingPlanMaster objects whose AuditPlanMaster.auditPlanEntity string is matching with provided filter value.
Thank you for your time and help in advance.
I had the same problem, here is a snippet of how I handled it. My problem was when accessing id field from inner usuario object, in my case, id would be like your auditPlanEntity, and usuario would be like auditplanMaster:
public static Specification<UsuarioErrorEquipo> usuarioContains(String codigoUsuario) {
return (root, query, builder) -> {
Path<Usuario> u = root.get("usuario");
return builder.equal(u.get("id"), codigoUsuario);
};
}
I believe, that in your case it should be something like:
Path<AuditPlanMaster> u = root.get("auditPlanId");
return builder.equal(u.get("auditPlanEntity"), "the value you want to compare");

OneToOne in Hibernate causes StackOverflow Exception when calling Mongo save

I have two entities :
Invoice :
#Entity
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Table(name = "invoices")
#JsonIgnoreProperties(ignoreUnknown = true)
public class Invoice implements Serializable {
private static final long serialVersionUID = 1L;
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid2")
#Column(columnDefinition = "CHAR(36)")
#Id
private String id;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "invoice")
private InvoiceSequence invoiceSequence;
... // skipped for brevity
InvoiceSequence
#Entity
public class InvoiceSequence {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long seqId;
#OneToOne
#JoinColumn(name = "invoice_id", nullable = false)
#JsonIgnore
private Invoice invoice;
... // skipped for brevity
When calling mongo save,as in :
#Override
public Invoice save(Invoice invoice) {
Invoice savedInv = invoiceRepository.save(invoice);
InvoiceSequence seq = new InvoiceSequence();
seq.setInvoice(savedInv);
InvoiceSequence savedSeq = invoiceSequenceRepository.save(seq);
savedInv.setInvoiceSequence(savedSeq);
return savedInv;
}
i get :
java.lang.StackOverflowError
at java.lang.Class.isInstance(Native Method)
at java.lang.Class.cast(Class.java:3368)
at java.lang.invoke.DirectMethodHandle$Accessor.checkCast(DirectMethodHandle.java:418)
at java.lang.invoke.DirectMethodHandle.checkCast(DirectMethodHandle.java:487)
at com.vulog.billing.domain.Invoice_Accessor_5oixbb.getProperty(Unknown Source)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:432)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:425)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:330)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:425)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:527)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:437)
What am i missing?
Thanks for any help

Resources