I have an error regarding deploying the backend trough docker on localhost 8080 .
When i run the website normally (started the postgres server from inteliji) it works properly.
When i try to deploy it trough docker i get the following error:
org.postgresql.util.PSQLException: ERROR: operator does not exist: uuid = bigint
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
Position: 580
The next code is an example of class using UUID
package com.ds.assignment1.ds2021_30244_rusu_vlad_assignment_1.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.util.UUID;
#Entity
#Data
public class Account {
#Id
#GeneratedValue(generator = "uuid4")
#GenericGenerator(name = "uuid4", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
private String username;
private String password;
private String role;
}
The error shows that the database column is UUID whereas the JPA entity is bigint. I should mention that this may be or may not be about the ID field of this entity.
As #Adrian-klaver said you have to look at position 580 of the SQL query, which you can do by enabling hibernate query logs and looking at the last hibernate SQL query log.
I had a similar problem, spending three days to finally resolve it. My problem was due to having multiple attribute types being different than their database type. As I was migrating from Long id to UUID, it made me confuse figuring out what the cause for my error was.
Related
I am creating a project in spring boot and as an example I am following an exercise on the internet where there is a primary key id and other fields. (the code is below).
When creating Entity / POJO class there is the #Id annotation which indicates that the member field below is the primary key of current entity with the addition of the #GeneratedValue (strategy = GenerationType.IDENTITY) annotation which is used to configure the increment of the specified column (field). And so far everything is clear.
Now a doubt arises; since the exercise I have to do does not have Id as primary key but has a code called PersonCode as primary key composed of both numeric and alphabetic characters (therefore it is not an auto-incremented field, but you have to enter it manually every time you create a new person ), what should be put in place of the #Id and #GeneratedValue annotations?
I hope I have been clear and I apologize for this question, I am a beginner.
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="student")
public class Student {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int student_id;
private String student_name;
private String student_email;
// Get and set methods
}
Since it's a manually generated value, you don't add #GeneratedValue. #Id must be used to indicate that this field represents the primary key.
Naturally, any time a Student is to be saved, it's student_id must be filled in beforehand, Spring won't generate and id for you.
Hover the class Product and you get 'Persistent entity 'Product' should have primary key'. From the quick search I did, I didn't find anything that was related.
package com.example.demo.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Table;
#Table(name="product")
#Data
#Entity
public class Product {
}
This means your entity class should have an ID field defined based on which jpa decides what type of primary key it needs to generate.
Define a field in entity class like below from the javax.persistence package.
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
i am trying to do a POC - using JpaRepository filter out the data by adding two conditions.
I have written a code like below
public interface TemplateRepository extends JpaRepository<Template, Long> {
List<Template> findByTemplateNameContains(String templateName);//This is Working Fine
List<Template> findByTemplateNameAndActiveFlagContains(String templateName, String activeFlag);// My POC
}
templateName column is a VARCHAR2 and activeFlag is a Char in the Oracle Database. I am trying to filter the data with both templatename
and activeFlag.
I pass the input object in SoapUI app (POST) request.
{
"netting":"karu_test",
"activeFlag": "Y"
}
but I get the below error
"Parameter value [%Y%] did not match expected type [java.lang.Character (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [%Y%] did not match expected type [java.lang.Character (n/a)]"
I understand this error like, the ACTIVE_FLAG column is CHAR(1) so type mismatch happend. But how to achieve the same functionality ?
More over .. how to use multiple table joins and condition in JpaRepository
I changed the type of activeFlag to Char still i get the same error.
Template class
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
#Entity
#Table(name="TEMPLATE_DEF")
#Getter
#Setter
public class Template {
#Column(name="TEMPLATE_ID")
#Id
private String nettingTemplateId;
#Column(name="TEMPLATE_NAME")
private String templateName;
#Column(name="LAST_UPDATE")
private Date lastUpdate;
#Column(name="UPDATE_USER_ID")
private Integer updUsrId;
#Column(name="ACTIVE_FLAG")
private char activeFlag;
#Column(name="VERSION")
private Integer Version;
#Column(name="CREATION_DATE")
private Date creationDate;
#Column(name="CREATE_USER_ID")
private Integer createUsrId;
}
Please try the below JPA Query
List<Template> findByTemplateNameContainingAndActiveFlagContaining(String templateName, Character activeFlag);
Your Active flag is a char so no point in putting containing for activeFlag rather do a exact match, change method signature to
List<Template> findByTemplateNameContainsAndActiveFlag(String templateName, char activeFlag);// My POC
I have tested it it will match name with like and activeFlag based on value of it
I have encountered the #DomainEvents and #AfterDomainEventsPublication annotation in spring Data JPA Reference Documentation. But I am not able to find the perfect example to explain about these annotaions
You can see sample in the original unit tests for EventPublishingRepositoryProxyPostProcessor EventPublishingRepositoryProxyPostProcessorUnitTests.java by Oliver Gierke in GitHub Repository of Spring Data Commons.
Description in base issue of Spring Jira DATACMNS-928 Support for exposing domain events from aggregate roots as Spring application events was useful for me.
UPDATE
This is simple and really working example by Zoltan Altfatter:
Publishing domain events from aggregate roots
Here is my example code:
package com.peaceelite.humanService;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.springframework.data.domain.AfterDomainEventPublication;
import org.springframework.data.domain.DomainEvents;
import java.util.*;
#Entity
public class SalesmanCustomerRelationship{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
/*getters & setters*/
#DomainEvents
Collection<Object> domainEvents() {
List<Object> result = new ArrayList<Object>();
result.add("Here should be an Event not a String, but, anyway");
return result;
}
#AfterDomainEventPublication
void callbackMethod() {
System.out.println("DATA SAVED!\n"+"WELL DONE");
}
}
This is an entity class managed by a spring data repository. Both #DomainEvents and #AfterDomainEventPublication happens after CrudRepository.save() being executed. One thing that is interesting is that #AfterDomainEventPublication ONLY works when #DomainEvents exists.
I'm learning Spring Data reference too, both this question and Dmitry Stolbov's answer helped me a lot.
I created a Spring Boot 1.3.5 POC with Spring Data JPA and Hibernate (4.3.11.Final in this version of Spring Boot). My backend database is Microsoft SQL Server, and our standard naming convention for database objects is pascal case (e.g. MySchema.MyTable.MyColumn). I used the javax.persistence.Table and javax.persistence.Column annotations to set the names, and added spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy to my application.properties file.
Everything worked perfectly. I even updated to Spring Boot 1.3.6 with no issues.
Now I moved to Spring Boot 1.4.0.RELEASE which uses Hibernate 5.0.9.Final, and the spring.jpa.hibernate.naming-strategy property is deprecated in favor of spring.jpa.hibernate.naming.strategy. I changed that property name, but left the EJB3NamingStrategy value. I also changed the other deprecated elements:
org.springframework.boot.orm.jpa.EntityScan to org.springframework.boot.autoconfigure.domain.EntityScan
org.springframework.boot.context.web.SpringBootServletInitializer to org.springframework.boot.web.support.SpringBootServletInitializer
org.springframework.boot.test.SpringApplicationConfiguration to org.springframework.boot.test.context.SpringBootTest (in my test classes)
Now the generated SQL uses the default camel case to underscore naming convention and not the pascal case that I had with EJB3NamingStrategy.
//application.properties
spring.data.jpa.repositories.enabled=true
spring.data.solr.repositories.enabled=false
spring.data.mongodb.repositories.enabled=false
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.hibernate.naming.strategy=org.hibernate.cfg.EJB3NamingStrategy
#spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy
//hibernate.properties
hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
hibernate.format_sql=true
//Principal.java
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import org.hibernate.envers.AuditTable;
import org.hibernate.envers.Audited;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#Entity
#Table(name="Principal", schema="Security")
#Audited
#AuditTable(value = "Principal", schema = "Audit")
public class Principal {
private static final Logger LOG = LoggerFactory.getLogger(Principal.class);
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "Id",
nullable = false)
private Long id;
#Column(name = "Username",
nullable = false,
unique = true)
#Size(min = 1, max = 64)
private String name;
#Column(name = "FirstName",
nullable = false)
#Size(min = 1, max = 64)
private String firstName;
#Column(name = "LastName",
nullable = false)
#Size(min = 1, max = 128)
private String lastName;
#Column(name = "IsEnabled",
nullable = false)
private boolean enabled;
//getters/setters omitted for brevity
}
orignal console output:
Hibernate:
select
principal0_.Id as Id1_8_,
principal0_.IsEnabled as IsEnable2_8_,
principal0_.FirstName as FirstNam3_8_,
principal0_.LastName as LastName4_8_,
principal0_.Username as Username5_8_
from
Security.Principal principal0_
where
principal0_.Username=?
new console output:
Hibernate:
select
principal0_.id as id1_7_,
principal0_.is_enabled as is_enabl2_7_,
principal0_.first_name as first_na3_7_,
principal0_.last_name as last_nam4_7_,
principal0_.username as username5_7_
from
security.principal principal0_
where
principal0_.username=?
2016-08-05 09:19:22.751 WARN 5032 --- [ XNIO-2 task-8] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 207, SQLState: S0001
2016-08-05 09:19:22.751 ERROR 5032 --- [ XNIO-2 task-8] o.h.engine.jdbc.spi.SqlExceptionHelper : Invalid column name 'is_enabled'.
2016-08-05 09:19:22.768 ERROR 5032 --- [ XNIO-2 task-8] io.undertow.request : UT005023: Exception handling request to /springbootsecurity/login
I've searched extensively, and found references to ImplicitNamingStrategy and PhysicalNamingStrategy; but plugging those in don't seem to work and is probably not the correct approach. I've also seen references to creating my own NamingStrategy. Is that the route I must take?
Is there a different setting for Hibernate 5 that will use the exact name I provide in the #Table and #Column annotations?
Is there a problem with the way I am defining the annotations?
I would like to say I ended up posting a silly question, but every direction I went talked about creating a custom naming strategy. The answer in my case, however, was simply using Hibernate's PhysicalNamingStrategyStandardImpl.
Added to application.properties:
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
From my naive analysis, I'm assuming this works because I am using the #Table and #Column annotations. The PhysicalNamingStrategyStandardImpl appears to simply use the name in those annotations as the database object name.
So my Hibernate generated query is once again formatted as:
Hibernate:
select
principal0_.Id as Id1_7_,
principal0_.IsEnabled as IsEnable2_7_,
principal0_.FirstName as FirstNam3_7_,
principal0_.LastName as LastName4_7_,
principal0_.Username as Username5_7_
from
Security.Principal principal0_
where
principal0_.Username=?
Reading #AmanTuladhar's link and this link from that post is where it eventually clicked for me. Thanks!
this is really a nice thread , for a beginner - who are migrating from spring boot 1.3 to 1.4 - below link contains all the stranded changes required , it also list all the deprecated options and contains some examples as well .
It gives overview about almost everything that you can use with application. For ex- Hibernate , Log4j , Junit/Mockito , Integration and so on . Please follow below link
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4-Release-Notes