Spring JPA save Single Entity cleared all existing postgresql table Data - postgresql

IMPL Class has following JPA SAVE statment.
detailBlockEntity.setLastUpdateUserId(ctx.getUserId());
detailBlockEntity.setOriginalUserId(ctx.getUserId());
DetailBlockEntity detailtBlockEntityRsp = detailBlockRepository.save(detailBlockEntity);
Entity Class:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
#Entity
#Table(
name = "detail_block",
schema = "pcrowner"
)
#TypeDef(
name = "StringJsonObject",
typeClass = StringJsonUserType.class
)
#NamedQuery(
name = "DetailBlockEntity.findAll",
query = "SELECT dtlBlock FROM DetailBlockEntity dtlBlock"
)
public class DetailBlockEntity extends BaseModelEntity {
private static final long serialVersionUID = -12477273943220535090L;
#Id
#GeneratedValue(
generator = "detail_block_seq",
strategy = GenerationType.SEQUENCE
)
#SequenceGenerator(
name = "detail_block_seq",
sequenceName = "detail_block_seq",
allocationSize = 10,
schema = "pcrowner"
)
#Column(
name = "detail_block_id",
unique = true,
nullable = false,
precision = 38
)
private Long id;
#Column(
name = "category_name"
)
private String ctgName;
Save execute on POSTGRE SQL Table cleared all existing data. Nothing strange in logs. It just happend behind the scenes. Please let me know if any one has any idea whats going on here?
I expected only one record to be saved in table. But instead cleared all data in table.

Related

PanacheEntityBase setting by default id as not nullable, even if specifying the reverse

I have an java class set as entity, which is defined as follow:
package com.redhat.bvbackend.player;
import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Entity;
import javax.persistence.SequenceGenerator;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.redhat.bvbackend.team.Team;
#Entity
public class Player extends PanacheEntityBase {
#Id
#Column(name = "player_id", nullable = true)
#SequenceGenerator(name = "playerSequence", sequenceName = "playerIdSequence", allocationSize = 1, initialValue = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "playerSequence")
public Long id;
public String name;
public String familyName;
public int age;
#OneToMany(mappedBy = "name", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
public List<Team> teams;
#NotNull
#Size(min = 1, max = 1, message = "Handed must be either Left or Right")
public String handed;
}
My class extends PanacheEntityBase and I am setting the column to allow nullable entries, and I am creating a generator to automatically increment the player_id for each new entry. My thought is that if a generator is defined, I shouldn't need to set the nullable since the generator already have an initialValue specified. Actually if I see the #column reference or not, it doesn't change I get always the same output. See below.
I would like to create an player as follow:
INSERT INTO player (age,familyname,handed,name) VALUES (25,'foo','x','y');
without the need to specify the id. However when I do so I get:
ERROR: null value in column "player_id" violates not-null constraint
DETAIL: Failing row contains (null, 25, foo, x, y).
What am I doing wrong? Thanks in advance.
Though you have a sequence generator created for that ID as playerIdSequence your column does not have a default value set.
The #GeneratedValue itself will be used within the panache insert sequence itself, and it will set the value of the ID when building the SQL request.
If you want to be able to automatically assign your ID when running raw SQL requests to the database yourself, you should assign a default value to something like nextval('playerIdSequence'). This way, it will get the next number in the sequence.
You can change the table like this:
alter table public.player alter column player_id set default nextval('playerIdSequence');

Spring boot JPA nnotationException: No identifier specified for entity, while having proper id

I have such DAO:
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.math.BigDecimal;
import java.util.UUID;
#Entity
#Table(name = "questionnaire_answer")
#Getter
#Setter
#NoArgsConstructor
public class QuestionnaireAnswer {
#Id
#Column(name = "id", nullable = false)
private UUID id;
and repository:
#Entity
#Table(name = "questionnaire_answer")
public interface QuestionaireRepository extends CrudRepository<QuestionnaireAnswer, UUID> {
sql:
CREATE TABLE questionnaire_answer (
id varchar(36) PRIMARY KEY,
...
)
but still I see an error:
AnnotationException: No identifier specified for entity:
what can I do wrong here ?
Blockquote
eh I am so blind, stupid mistake
#Repository should be in QuestionaireRepository
but I put there table and entity :)) it was end of my day..
today I realized what had happened.

JPA won't set default value to boolean column in Postgres database

I am trying to add a new column to a table with the default value "false".
I tried
private boolean fo_create = false;
#Builder.Default
private Boolean fo_created = Boolean.false;
#Column(columnDefinition = "boolean default false")
private boolean fo_created = false;
But none of those work. With the "Boolean" type, the column is created but remains null. With the boolean type, JPA throws an error and telling that it can't set the boolean to null ( although I specified the default value to false )
Can somebody help me solve this ?
Entity class code
package com.example.demo.Entity;
import java.math.BigInteger;
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 lombok.Data;
/**
* #author Sathiyaraj Ramamurthy 16 Nov 2021 5:47:26 AM
*
*/
#Data
#Entity
#Table(name = "event")
public class EventDemo {
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#Column(name = "event_name")
private String eventName;
#Column(name = "status", columnDefinition="tinyint(1) default 1")
private boolean status;
}
Postman request Details
I'm using MySQL database. I believe it would be worked in Postgres as well

What can cause an id annotated with #GeneratedValue(strategy = GenerationType.IDENTITY) to be null

Entities
AttributeScore
import java.io.Serializable;
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 com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
#Data
#Entity
#NoArgsConstructor
#AllArgsConstructor(onConstructor = #__({#JsonIgnoreProperties(ignoreUnknown = true)}))
#Table(name = "ATTRIBUTE_SCORE")
#JsonInclude(JsonInclude.Include.NON_NULL)
public class AttributeScore implements Serializable {
/**
*
*/
private static final long serialVersionUID = 621935018037696921L;
public final static int ABOVE_VALUE = 80;
public final static int AT_VALUE = 70;
#Getter(onMethod = #__({
#Id,
#GeneratedValue(strategy = GenerationType.IDENTITY),
#Column(name = "ID")
}))
private Long id;
/** Attribute Score */
#Getter(onMethod = #__({
#ManyToOne(fetch = FetchType.EAGER),
#JoinColumn(name = "ATTRIBUTE_ID")
}))
private Attribute attribute;
/** Score */
#Getter(onMethod = #__({
#Column(name = "SCORE")}))
private int score;
}
Attribute.java
import java.io.Serializable;
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 com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
#Data
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "ATTRIBUTES")
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Attribute implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8847589625501522335L;
public static final int MAX_POINTS = 3;
/** Attribute id */
#Getter(onMethod = #__({
#Id,
#GeneratedValue(strategy = GenerationType.IDENTITY),
#Column(name = "ID")
}))
private Long id;
/** Attribute Name */
#Getter(onMethod = #__({
#Column(name = "NAME", length = 500)}))
private String name;
/** Weight */
#Getter(onMethod = #__({
#Column(name = "WEIGHT")}))
private int weight;
/** Points */
#Getter(onMethod = #__({
#Column(name = "DISPLAY_ORDER")}))
private int displayOrder;
/** Required */
#Getter(onMethod = #__({
#Column(name = "REQUIRED")}))
private boolean required;
}
Invocation
from a #Stateless #LocalBean class.
protected E saveInstance(E entity) {
if (entity == null) {
throw new NosisEJBValidationException("entity cannot be null");
} else {
I id = getId(entity);
if (id == null) {
em.persist(entity);
logger.info(Logger.EVENT_UNSPECIFIED, "entity of type '" + entity.getClass().getSimpleName()
+ "' with id '" + getId(entity) + "' created.");
} else {
entity = em.merge(entity);
logger.info(Logger.EVENT_UNSPECIFIED,
"entity of type '" + entity.getClass().getSimpleName() + "' with id '" + id + "' updated.");
}
}
return entity;
}
calling the above saveInstance method results in the following:
SQL Error: 1400, SQLState: 23000
ORA-01400: cannot insert NULL into ("COMMON_USER"."ATTRIBUTE_SCORE"."ID")
The question's name pretty much says it all. I am trying to persist a new instance of ATTRIBUTE_SCORE. The entity being passed into saveInstance has an id of null. Any idea why this isn't working.
I honestly do not know where to look.
EDIT
it turns out that the wrong sql is being generated:
Hibernate: insert into common_user.ATTRIBUTE_SCORE (ATTRIBUTE_ID, SCORE) values (?, ?)
it should be:
Hibernate: insert into common_user.ATTRIBUTE_SCORE (ID, ATTRIBUTE_ID, SCORE) values (?, ?, ?)
so new question: why is the id field being excluded?
If you use the strategy javax.persistence.GenerationType.IDENTITY for #GeneratedValue your table must have an identity generator. This can be done including an AUTO_INCREMENT to your primary key.
if you don't set any value for your id field, it is supposed to be null or default value (or it will do an auto increment if you set that attribute).
The #GeneratedValue annotation just tells Hibernate that the database is generating this value itself. So the AUTO_INCREMENT should be defined in the database as well.
Similar question at this link,
Hibernate #GeneratedValue null error for primary key

JPA Repository not working properly

I am new to Open JPA and I am migrating my application DB services from JPA with Hibernate as vendor provider to JPA with OpenJPA as vendor Provider. Everything is fine, but I am not able to migrate my repositories. I am getting below error:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property find found for
type com.entities.LevelPossibilityData
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:271)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:245)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:72)
Here is my entity:
package com.entities;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import java.lang.reflect.Field;
#Entity
#Table(name = "LEVEL_POSSIBILITY_DATA", schema = "DEV")
#NamedQueries({
#NamedQuery(name = "LevelPossibilityData.findAllPossibilityGenIds", query = "SELECT distinct possibilityData.levelPossibilityGenId FROM LevelPossibilityData possibilityData where possibilityData.userCode is not null and possibilityData.possibilityType=?1 order by possibilityData.levelPossibilityGenId asc")})
public class LevelPossibilityData implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
#Column(name = "LEVEL_SEQ_ID")
private BigDecimal levelSeqId;
#Column(name = "LEVEL_USER_CODE")
private String userCode;
#Column(name = "LEVEL_USER_POSSIBILITY_TYPE")
private String possibilityType;
#Column(name = "LEVEL_POSSIBILITY_GENERATOR_ID")
private String levelPossibilityGenId;
}
and my Repository:
package com.dao;
import java.io.Serializable;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.entities.LevelPossibilityData;
public interface LevelPossibilityDataRepository<ID extends Serializable> extends JpaRepository<LevelPossibilityData, Serializable> {
public List<LevelPossibilityData> findAllPossibilityGenIds(String possibilityType);
}
Can you please help me out in rectifying this error?
I was able to solve the issue by removing Named Queries from entity. I introduced queries directly into Repository by using #Query annotation.
Just one catch, if you are using openJPA and trying to use #Query in Repository, try to use full path of the entities used e.g.
use "com.entities.LevelPossibilityData" instead of "LevelPossibilityData" in your query i.e. your query should be "select level from com.entities.LevelPossibilityData level" instead of "select level from LevelPossibilityData level".
I hope this explaination will be helpfull. Thanks everybody for devoting time on this.