Spring JPaRepository not recognizing Column - postgresql

I am working on a simple spring endpoint. My current db table sql is:
CREATE TABLE develop.usermetrics (
metricId SERIAL PRIMARY KEY,
uid varchar(12),
deptCode varchar(10),
orgGroup varchar(10),
orgUnit varchar(10),
orgCode varchar(10),
workLocationCode varchar(10),
campusId varchar(20),
userRole varchar(50),
metricDate timestamp
);
And my entity contains:
#Table(name = "usermetrics")
#Entity
public class UserMetricsEntity {
#Id
#Column(name = "metricId")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long metricId;
#Column(name = "uid")
private String uid;
#Column(name = "deptCode")
private String deptCode;
#Column(name = "orgGroup")
private String orgGroup;
#Column(name = "orgUnit")
private String orgUnit;
#Column(name = "orgCode")
private String orgCode;
#Column(name = "workLocationCode")
private String workLocationCode;
#Column(name = "campusId")
private String campusId;
#Column(name = "userRole")
private String userRole;
#Column(name = "metricDate")
private LocalDateTime metricDate;
When calling the save method of the repository I get the error:
UserMetricsEntity{metricId=null, uid='105735781', deptCode='Z05511', orgGroup='F&O', orgUnit='CIO', orgCode='0F', workLocationCode='MPG', campusId='GDLPLANT', userRole='Fullstack Developer', metricDate=2021-11-01T12:45:22.588191}
2021-11-01 12:45:23.029 WARN 57529 --- [nio-8082-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42703
2021-11-01 12:45:23.029 ERROR 57529 --- [nio-8082-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: column "campus_id" of relation "usermetrics" does not exist
The first line of the log being a toString of the Entity.

Even though I named with camel case on the table creating sql, pgadmin changed the caps to lowercase. I changed the naming convention on the entity class to all lowercase and it worked.

Related

org.postgresql.util.PSQLException: ERROR: null value in column "id" violates not-null constraint, Id Colums not able generate by sequcece in Hibernat

I am getting an error that Id column is not able to generate.
which will have the Getters and Setters.
Note: In my case, Primary Key was bookingId.
"Id" has to be a sequence number.
Below is the save method.
At the time of save is was not able to generate value for the column.
Below is My Entity.
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Id
#Column(name = "booking_id")
private String bookingId;
#Column(name = "booked_by")
private String bookedBy;
#Column(name = "booking_status")
private int bookingStatus;
#Column(name = "booking_rcv")
private Date bookingRcv;
#Column(name = "chargeable_kgs")
private BigDecimal chargeableKgs;
}
Here we will have all the getters and setters, Constructors, hashcode, and equals methods.
#Transactional
#Override
public Booking saveBooking(Booking booking) {
Booking savedBooking = bookingRepository.save(booking);
if (savedBooking.getId() != null) {
booking.setId(savedBooking.getId());
}
booking.setVersion(savedBooking.getVersion());
bookingRepository.flush();
// bookingRepository.refresh(booking);
LOGGER.debug("savedbooking id::" + savedBooking.getId());
return savedBooking;
}
I am using postgre DB and Hibernate.

Spring Data Native Query uses VARBINARY for null String #Param

I have a JpaRepository, with a native query in it:
#Query (value = "SELECT t.team_name FROM teams t " +
"WHERE (:teamcode IS NULL OR t.team_code = :teamcode) ",
nativeQuery = true)
List<Object[]> getTeamNames(#Param("teamcode") #Nullable String teamCode);
If I pass a non-null value, it works fine - the binding parameter type is VARCHAR. However, if I pass in a null parameter value, then the binding type is VARBINARY, and the query fails with the error:
SQL Error: 0, SQLState: 42883
ERROR: operator does not exist: character varying = bytea
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
Table:
CREATE TABLE teams (
team_id BIGINT NOT NULL,
team_code VARCHAR(24) NOT NULL,
team_name VARCHAR(200),
team_desc VARCHAR(2000),
)
Entity:
#Entity
#DynamicUpdate
#Getter
#Setter
#EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
#Table(name = "teams", schema = "public")
public class Team extends BaseEntity
{
#Id
#Column(name = "team_id", nullable = false)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ent_generator")
#SequenceGenerator(name = "ent_generator", sequenceName = "entity_seq", allocationSize = 1)
private long teamId;
#EqualsAndHashCode.Include
#Basic
#Column(name = "team_code", length = 24)
private String teamCode;
#Basic
#Column(name = "team_name", length = 200)
private String teamName;
#Basic
#Column(name = "team_desc", length = 2000)
private String teamDescription;
}
How do I resolve this?

JPA entity sequence generating

In spring boot JPA I tried to implement sequence generator but it is not working.
the following is my entity
#Entity
#Table(name = "role_level")
public class RoleLevel implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#SequenceGenerator(name = "role_level_sequence", sequenceName = "role_level_id_seq",allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "role_level_sequence")
#Column(name = "id", updatable = false)
private Long id;
#Column(name = "role_level")
private String roleLevel;
#Column(name = "role_level_description")
private String roleLevelDescription;
//getters and setters
}
when I insert value in directly through the database then next sequence from the db is not getting in jpa.it shows
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "role_level_pkey"
Detail: Key (id)=(7) already exists.
But the console shows
Hibernate: select nextval ('role_level_id_seq')
I think its not working.
Is there any solution for this.?

JPA repository retrieve custom primary key value after save

I have an entity class pointing to postgresql table. Below is table structure. The paymentreferencenumber is the PK which is populated by a trigger. id field is the sequence generated field. When i try to save in this table using JPARepository save method it inserts the first record. But after that it fails due to the primary key constraint. Since PK is a string type and generated using trigger I am specifying generator strategy as 'select'. Can anyone help me with this blocker and point me in the right direction. Thanks
Table structure --
custId serial not null,
paymentreferencenumber varchar(32) not null
constraint customers1_pkey
primary key,
firstname varchar(255),
lastname varchar(255)
Entity class --
#Entity
#Table(name = "customersnew")
public class Customer implements Serializable {
private static final long serialVersionUID = -1L;
#GeneratedValue(generator = "seq")
#GenericGenerator(name="seq", strategy="sequence", parameters = { #Parameter(name="key", value = "customersnew_custid_seq")})
#Column(name = "custid")
private long id;
#Id
#GeneratedValue(generator = "trigger_generated")
#GenericGenerator(name="trigger_generated", strategy="select", parameters = { #Parameter(name="key", value = "id")})
#Column(name = "paymentreferencenumber")
private String refNum;
#Column(name = "firstname")
private String firstName;
#Column(name = "lastname")
private String lastName;
}
--- Controller using JPA save
#RestController
public class CustomerController {
#Autowired
CustomerRepository repository;
EntityManagerFactory emf;
public CustomerController(CustomerRepository repository, EntityManagerFactory emf) {
this.repository = repository;
this.emf = emf;
}
#PostMapping("/create")
public String create(#RequestBody CustomerUI customer){
// save a single Customer
Customer returnObj = repository.saveAndFlush(new Customer(customer.getFirstName(), customer.getLastName()));
PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
Object retObj = util.getIdentifier(returnObj);
return "Customer is created";
}
If you don't specify an id generation strategy, Hibernate will use GenerationType.AUTO. This will result in any of
AUTO - either identity column, sequence or table depending on the
underlying DB.
If you look here, you'll notice all of those generate ids of type long, short or int, not of type String.
Say you wanted a String UUID as an id, you could use
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid2")
#Column(name = "paymentreferencenumber")
private String refNum;

JPA entity and Database Table mapping Validation constraint(s) violated

I have two table:
CREATE TABLE [LeTYPE](
[LeNAME] [varchar](100) NOT NULL,
[Le_DESC] [varchar](500) NULL,
[LeFOR] [varchar](50) NOT NULL,
CONSTRAINT [PK_LeTYPE] PRIMARY KEY CLUSTERED
(
[LeNAME] ASC
)
)
CREATE TABLE [Le](
[SN] [int] IDENTITY(1,1) NOT NULL,
[LeNAME_FK] [varchar](100) NOT NULL,
[Le_SN] [int] NULL,
[LOWERRANGE] [float] NOT NULL,
[UPPERRANGE] [float] NOT NULL,
[Le_DESC] [varchar](500) NULL,
[COLOR] [varchar](45) NULL,
CONSTRAINT [Le_pk] PRIMARY KEY CLUSTERED
(
[SN] ASC
))
GO
ALTER TABLE [Le] WITH CHECK ADD CONSTRAINT [FK_Le_LeTYPE] FOREIGN KEY([LeNAME_FK])
REFERENCES [LeTYPE] ([LeNAME])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [Le] CHECK CONSTRAINT [FK_Le_LeTYPE]
GO
One tuple in LETYPE will have many LE.
JPA Entity generated by netbeans:
public class Letype implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 100)
#Column(nullable = false, length = 100)
private String Lename;
#Size(max = 500)
#Column(name = "Le_DESC", length = 500)
private String LeDesc;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 50)
#Column(nullable = false, length = 50)
private String Lefor;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "LenameFk", fetch = FetchType.LAZY)
private List<Le> LeList;
}
public class Le implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Column(nullable = false)
private Integer sn;
#Column(name = "Le_SN")
private Integer LeSn;
#Basic(optional = false)
#NotNull
#Column(nullable = false)
private double lowerrange;
#Basic(optional = false)
#NotNull
#Column(nullable = false)
private double upperrange;
#Size(max = 500)
#Column(name = "Le_DESC", length = 500)
private String LeDesc;
#Size(max = 45)
#Column(length = 45)
private String color;
#JoinColumn(name = "LeNAME_FK", referencedColumnName = "LeNAME", nullable = false)
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private Letype LenameFk;
}
Now, What I wanted was if I add a LETYPE from JSF view I would like to add multiple LE also at the same time.
LETYPE
-LE1
-LE2
-LE3
The structure of entities generated by netbean has letypeList with in Le and not the opposite.
Is my database structure wrong or How to do it right?
Yes i feel like you got wrong relationship in database between LE and LETYPE.
Current relation from JPA perspective is treated as One LE can have Many LETYPE that is why you see below code in LE entity class.
#OneToMany(mappedBy = "LeFk")
private List<Letype> letypeList;
But it is wrong, you need Reverse relation i.e, One LETYPE can have Many LE (One-To-Many).
Basically your database structure is wrong I guess, you have to maintain FK column in LE table, where as currently you maintaining in LETYPE.
In database world, FK column always resides in Many side , in your case i.e. LE table.
What to do now
Remove FK column in LETYPE table
Add FK column in LE table referring to LETYPE table primary key
Generate JPA Entity again
Then you see right JPA code with right relation ship.
I hope then you should be able to do what you need.
"What I wanted was if I add a LETYPE from JSF view I would like to add multiple LE also at the same time" means that the LETYPE can be seen as the component class, and the LE as the composite class, so you should reverse the mapping annotations. To illustrate this and what #Jayasagar well explained in addition, the two classes's forms look like :
Letype.java :
public class Letype implements Serializable {
...
#OneToMany(mappedBy="letype")
private List<Le> les;
}
Le.java :
public class Le implements Serializable {
...
#ManyToOne
#JoinColumn(name = "Letype_FK", referencedColumnName = "LENAME")
private Letype letype;
}