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
Related
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');
I want to get the SQL to join Summoner, summoner_match and match using JPASQLQuery class.
like this.
SELECT
*, row_number()OVER()
FROM
summoner s
LEFT OUTER JOIN
summoner_match sm
on
s.account_id= sm.account_id
LEFT OUTER JOIN
match m
on
sm.game_id = m.game_id
I add my source code below.
package gg.om.omgg.domain.summoner;
import gg.om.omgg.domain.match.Match;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
#Getter
#NoArgsConstructor
#Entity
public class Summoner implements Serializable {
#Id#Column(length=56)
private String id;
#Column(name="account_id", length=56)
private String accountId;
private int profileIconId;
private long revisionDate;
private String name;
#Column(length=78)
private String puuid;
private long summonerLevel;
#OneToMany
#JoinTable(name="summoner_match",
joinColumns = #JoinColumn(name="account_id"),
inverseJoinColumns = #JoinColumn(name="game_id")
)
private List<Match> matches = new ArrayList<>();
//...
}
package gg.om.omgg.domain.match;
import gg.om.omgg.domain.participant.Participant;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Getter
#NoArgsConstructor
#Entity
public class Match {
#Id
#Column(name="game_id")
private long gameId;
private int queueId;
private String platformId;
private int seasonId;
private long gameCreation;
private long gameDuration;
#OneToMany
#JoinColumn(name = "game_id", referencedColumnName = "game_id")
List<Participant> participants = new ArrayList<>();
//...
}
.
.
.
Seems to have found a way.
I will be an advisor.
package gg.om.omgg.domain.summoner;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.querydsl.jpa.sql.JPASQLQuery;
import com.querydsl.sql.SQLExpressions;
import gg.om.omgg.domain.match.QMatch;
import gg.om.omgg.domain.participant.QParticipant;
import gg.om.omgg.web.dto.SummonerIntegrationInformationResponseDTO;
import lombok.RequiredArgsConstructor;
#RequiredArgsConstructor
public class SummonerCustomRepositoryImpl implements SummonerCustomRepository {
// JPASQLQuery class is registered as #Bean in advance
private final JPASQLQuery jpasqlQuery;
#Override
public void mySolution() {
QSummoner summoner = QSummoner.summoner;
QMatch match = QMatch.match;
// Create Qclass for #JoinTable
QSummoner summoner_match1 = new QSummoner("summoner_match");
QMatch summoner_match2 = new QMatch("summoner_match");
jpasqlQuery
.select(summoner, match, SQLExpressions.rowNumber().over())
.from(summoner)
.leftJoin(summoner_match1)
.on(summoner.accountId.eq(summoner_match1.accountId))
.leftJoin(match).on(summoner_match2.gameId.eq(match.gameId))
.fetch();
}
}
I have three class: User, Admin, NormalUser
Admin and NormalUser extends User Class and I use Single Table Strategy for inheritance when mapped to derby db table and I found out there will be error if I write a named query using inherited attribute in NormalUser class. More information can be referred from below code:
package entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.MappedSuperclass;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.STRING)
#DiscriminatorValue("Null")
#Table(name="ALLUSER")
#NamedQueries({
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
#NamedQuery(name = "User.findByAccount", query = "SELECT u FROM User u WHERE u.account = :account")
})
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String account;
private String password;
private String userType;
public User() {
super();
}
public User(String account, String password) {
super();
this.account = account;
this.password = password;
}
#Id
#Column(name = "account")
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
#Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "user_type", insertable = false, updatable = false, nullable = false)
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
#Override
public String toString() {
return account;
}
}
package entity;
import java.io.Serializable;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
#Entity
#DiscriminatorValue("Normal")
#NamedQueries({
#NamedQuery(name = "NormalUser.findAll", query = "SELECT u FROM NormalUser u")
})
public class NormalUser extends User implements Serializable{
/**
*
*/
//private String account;
private static final long serialVersionUID = 1L;
private LinkedHashSet<Customer> customers;
public NormalUser() {
super();
}
#OneToMany(fetch=FetchType.EAGER, mappedBy="user", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) //delete user will delete all customer
public LinkedHashSet<Customer> getCustomers() {
return customers;
}
public void setCustomers(LinkedHashSet<Customer> customers) {
this.customers = customers;
}
// #Column(name = "account")
// //have to override in order to get account to use
// public String getAccount() {
// return account;
// }
//
// public void setAccount(String account) {
// this.account = account;
// }
}
If I write a named query using normal user's inherited attribute:
package entity;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
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.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
#Entity
#Table(name="CUSTOMER")
#NamedQueries({
#NamedQuery(name = "Customer.findAll", query = "SELECT c FROM Customer c order by c.customerID desc")
,#NamedQuery(name = "Customer.findByUser", query = "SELECT c FROM Customer c WHERE c.normalUser.account = :account")
})
public class Customer implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int customerID;
private Industry customerIndustryType;
private String customerName;
private Address customerAddress;
private String customerNationality;
private Date customerAddedDate;
private Double customerDiscountRate;
private String customerScale;
private List<Contact> customerContacts;
private NormalUser normalUser;
//getter and setter omited .....
}
Errors will be thrown when running it and it is apparently related to this query for accessing parent attribute:
Actually, I also try criteria API and it also failed:
// customers = entityManager.createNamedQuery("Customers.findByAccount", Customer.class).setParameter("account", role).getResultList();
// CriteriaBuilder builder = entityManager.getCriteriaBuilder();
// CriteriaQuery<Customer> criteriaQuery = builder.createQuery(Customer.class);
// Root<Customer> c = criteriaQuery.from(Customer.class);
// criteriaQuery.select(c).where(builder.equal(c.get("normalUser").get("account"), role)); //(p.get("price"), budget));//danger4
// Query query = entityManager.createQuery(criteriaQuery);
// //List<Property> properties = query.getResultList();
// customers = query.getResultList();
So How can I use the parent object's attribute? It should not be like this. If I extends the class, I will have all the inherited attributes, isn't it?
---------------------------------------------Update-----------------------------
The inherited attribute can be used in JPQL. It is just that we have to always remember to check the getter name when you annotation on it, which is what is resolved in JPQL.
Hope future visitors remember to pay attention to details.
LOL, The biggest bug comes from the easiest mistake.
The good thing is that due to this error, I have to access customers via user.getCustomers() since it is bidirectional. As a result, I learn a lot to maintain bidirectional relationship.
I am trying to access particular column from different table using Spring Data JPA Inner Join.
I created four model. AccountModel is main model.
i used manyToOne mapping in AccountModel to the other three model(DepartmentModel,AccountCPCMappingModel,InvestigatorModel). I am trying to access particular column from four table using native Query in AccountRepository
This is my application scenario.
1.AccountModel.java
package com.demo.model;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="account")
public class AccountModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
public Integer naccountid;
public String namount;
public String sacctdesc;
public Integer naccountcpcmappingid;
public Integer nindirectcostrate;
public Integer nagencyid ;
public Integer ndeptid ;
public String sgrantnum;
public Timestamp dstartdate;
public Timestamp denddate;
public String slocation;
public String sclientacctid;
public Integer ninvestigatorid;
public Integer ninstid;
public Integer ntempaccountid;
#ManyToOne(optional = true)
#JoinColumn(name="ndeptid",insertable = false, updatable = false)
public DepartmentModel department;
#ManyToOne(optional = true)
#JoinColumn(name="ninvestigatorid",insertable = false, updatable = false)
public InvestigatorModel investigator;
#ManyToOne(optional = false)
#JoinColumn(name="naccountcpcmappingid",insertable = false, updatable = false)
public AccountCPCMappingModel accountCPC;
//...Getter and Setter
}
2 DepartmentModel
package com.demo.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "department")
public class DepartmentModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
public Integer ndeptid;
public String sdeptname ;
public Integer ninstid ;
public Boolean bislocked;
public String sclientdeptid;
public Integer nsurveymethodid;
public Boolean bisjointuse;
public Integer ntempdeptid;
public Boolean balternatejointusepercentage;
public Integer ndivid;
//...Getter and Setter
3.InvestigatorModel
package com.demo.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="investigator")
public class InvestigatorModel implements Serializable{
private static final long serialVersionUID = 1L;
#Id
public Integer ninvestigatorid;
public String sinvestigatorname;
public Integer ninstid ;
public String stitle;
public Integer ntempinvestigatorid;
public Integer nempid;
AccountRepository
package com.demo.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.demo.model.AccountModel;
#Repository
public interface AccountRepository extends JpaRepository<AccountModel, Integer>{
#Query(value="select acct.sclientacctid,acct.sacctdesc,acct.slocation,invest.sinvestigatorname, \r\n" +
"dept.sclientdeptid,dept.sdeptname,acp.sccpcode \r\n" +
"from Account acct join Department dept on acct.nDeptID=dept.nDeptID \r\n" +
"join Investigator invest on acct.nInvestigatorID=invest.nInvestigatorID \r\n" +
"join AccountCPCMapping acp on acct.nAccountCPCMappingID=acp.nAccountCPCMappingID \r\n" +
"where acct.nInstID=60 \r\n" +
"order by acct.sclientacctid Asc",nativeQuery=true)
List<Object[]> findByNaccountid();
}
AccountService
package com.demo.services;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.demo.model.AccountModel;
import com.demo.repository.AccountRepository;
#Service
public class AccountService {
#Autowired
AccountRepository accRepo;
public List<AccountModel> findLocation()
{
return accRepo.findBySlocation();
}
public Set<Object[]> gridLoad()
{
Set<Object[]> gridObj=accRepo.findByNaccountid();
return gridObj;
}
}
AccountController
package com.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.demo.model.AccountModel;
import com.demo.services.AccountService;
#RestController
#RequestMapping("/SpaceStudy/SpaceAdmin")
public class AccountController
{
#Autowired
AccountService accService;
#CrossOrigin(origins="*")
#GetMapping("/AccountMaintenance/LoadLocation")
public List<AccountModel> findLocation()
{
return accService.findLocation();
}
#CrossOrigin(origins="*")
#PostMapping("/AccountMaintenance/LoadGrid")
public Set<Object[]> GridLoad()
{
return accService.gridLoad();
}
}
I am getting output in this format
But I want output in JSON Format like this (key,value pairs)
sample output
[
{
"userId": 1,
"id": 1
}
]
Can any one help me what i need to change in my code for json data.
Your query should return List<Object[]> and not List<AccountModel>.
JPA equivalent query will be something like this.
Query("select acct.sclientacctid,acct.sacctdesc,acct.slocation,invest.sinvestigatorname, dept.sclientdeptid,dept.sdeptname,acp.sccpcode
from AccountModel acct join acct.department dept join acct.investigator invest join acct.accountCPC acp
where acct.nInstID= :instId
order by acct.sclientacctid")
List<Object[]> findByInstId (#Param("instId") Integer instId);
This will return you a List of Object array and the array will have the columns in order it appears in the select. Give it a try.
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