I'm trying to insert a record with composite primary key, but at the time of saving a new record I get this message:
e = (org.springframework.orm.jpa.JpaSystemException)
org.springframework.orm.jpa.JpaSystemException: Could not set field
value [POST_INSERT_INDICATOR] value by reflection...
#Getter
#Setter
#Entity
#EqualsAndHashCode
#Table(name = "produto")
#IdClass(ProdutoId.class)
public class Produto implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_produto")
private Long idProduto;
#Id
#Column(name = "oficina", insertable = false, updatable = false)
private Long idOficina;
#ManyToOne
#JoinColumn(name = "oficina")
private Oficina oficina;
}
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode
#Data
public class ProdutoId implements Serializable {
public Long idProduto;
public Long idOficina;
}
#Repository
public interface ProdutoRepository extends JpaRepository<Produto, ProdutoId> {}
Has anyone ever seen a bug like this?
To create composite primary key you can refer this example,
#Entity
#Table(name="testuserrole")
public class UserRole{
#EmbeddedId
private UserRoleId id = new UserRoleId();
public UserRoleId getId() {
return id;
}
public void setId(UserRoleId id) {
this.id = id;
}
#Transient
public long getUserId() {
return id.userId;
}
public void setUserId(long userId) {
id.userId=userId;
}
#Transient
public long getRoleId() {
return id.roleId;
}
public void setRoleId(long roleId) {
id.roleId=roleId;
}
}
#Embeddable
class UserRoleId implements Serializable {
#Column(name = "user_id")
public long userId;
#Column(name = "role_id")
public long roleId;
}
Related
I have a table master table user ,topics table and comments table
where in for a single topic there can be multiple comments
user table will be already populated.
I will get a post request to save the topic with structure like below
{
"topicId":"T001",
"title":"stackoverflow",
"commentBeans":[
{
"comment":"developer platform"
},
{
"comment":"developer communtiy"
}
]
}
Frameworks used:
spring boot
JPA
DB : postgressql
I am able to save the data the traditional way (i.e get the request and save topic bean first. get the primarykey from saved entity and loop the list of commentbean where user num will be set dynamically by another get service and save them)
I wanted to know if there is anyway to save the data with single save query.
#Entity
#Table(name ="user")
public class User implements Serializable {
#Id
#Column(name = "user_num")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long userNum;
#Column(name = "user_id")
private String userId;
#Column(name = "username")
private String userName;
}
#Entity
#Table(name = "topics")
public class TopicBean implements Serializable {
#Id
#Column(name = "topic_num")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long topicNum;
#Column(name = "topicId")
private String topicId;
#Column(name = "title")
private String title;
#OneToMany(mappedBy="topicBean")
private List<CommentBean> commentBeans;
}
#Entity
#Table(name = "comments")
public class CommentBean implements Serializable {
#EmbeddedId
private CommentBeanKey key;
#Column(name = "comment")
private string comment;
#ManyToOne
#JoinColumn(name="topic_num")
private TopicBean topicBean;
#ManyToOne
#JoinColumn(name="user_num")
private TopicBean topicBean;
}
#Embeddable
public class CommentBeanKey implements Serializable{
private static final long serialVersionUID = 5889249943605061539L;
#Column(name ="topic_num")
private Long topicNum;
#Column(name ="user_num")
private Long userNum;
}
I saw the below link and am little worried if am doing the wrong way. any help is appreciated.
https://thoughts-on-java.org/hibernate-tips-how-to-map-an-entity-to-multiple-tables/
Parent.java
#Entity
#Table(name = "parent")
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#ToString
public class Parent {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int parentId;
private String name;
#OneToMany(mappedBy="parent",fetch=FetchType.LAZY,cascade = CascadeType.PERSIST)
private List<Child> child = new ArrayList<Child>();
}
Child.java
#Entity
#Table(name = "child")
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#ToString
public class Child {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int childId;
private String account;
#ManyToOne(fetch = FetchType.LAZY, targetEntity = Parent.class)
#JoinColumn(name="parentId", referencedColumnName = "parentId", nullable = false)
private Parent parent;
}
Controller.java
//save Child with Parent at same
#PostMapping(value = "/onetomany")
public String OneToMany(#RequestBody Parent parent)
{
System.out.println("Parent: "+parent.toString());
for (Child child : parent.getChild()) {
child.setParent(parent);
}
parent.setChild(parent.getChild());
parentRepository.save(parent);
return "saved";
/*{
"name":"Romil",
"child":[
{"account":"1"},
{"account":"2"}
]
}*/
}
//save Child with Parent's ID
#PostMapping(value = "/onetomanyPID")
public String OneToMany(#RequestBody Child child)
{
child.setParent(child.getParent());
childRepository.save(child);
return "saved";
/*{
"account":"3",
"parent":{
"parentId":"1",
"name":"Romil"
}
}*/
}
I have 5 tables every table has relation one to many with the next table
Project_t -> project_level1_t -> project_level2_t -> project_level3_t -> project_level4_t
I want to user hibernate with these tables
CREATE TABLE project_t
(
projectid serial NOT NULL,
address1 character varying(128),
postcode character varying(7),
city character varying(64),
level_four_name character varying(128),
CONSTRAINT project_t_pkey PRIMARY KEY (projectid),
CONSTRAINT projectcode_unique UNIQUE (projectcode)
)
And project_level1_t
CREATE TABLE project_level1_t
(
projectlevel1id integer NOT NULL DEFAULT nextval('project_level1_t_projectlevel1pk_seq'::regclass),
levelname character varying(256),
projectid integer,
CONSTRAINT project_level1_t_pkey PRIMARY KEY (projectlevel1id),
CONSTRAINT project_level1_t_project_t_fkey FOREIGN KEY (projectid)
REFERENCES project_t (projectid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
And project_level2_t
CREATE TABLE project_level2_t
(
projectlevel2id integer NOT NULL DEFAULT nextval('project_level2_t_projectlevel2_seq'::regclass),
levelname character varying(256),
projectlevel1id integer,
CONSTRAINT project_level2_t_pkey PRIMARY KEY (projectlevel2id),
CONSTRAINT project_level2_t_projec_level_1_fkey FOREIGN KEY (projectlevel1id)
REFERENCES project_level1_t (projectlevel1id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
And this is the Repository files
package ma.eurnet.mp.tables.model;
import javax.persistence.GenerationType;
#JsonAutoDetect
#Entity
#Table(name = "project_t")
public class ProjectRepository implements Serializable {
private static final long serialVersionUID = 1L;
public ProjectRepository() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "projectid")
private Long projectId;
#OneToMany(fetch = FetchType.EAGER, mappedBy="project")
#JsonIgnore
private List<ProjectLevel1Repository> projectlevel1 = new ArrayList<ProjectLevel1Repository>();
public Long getProjectId() {
return projectId;
}
public void setProjectId(Long projectId) {
this.projectId = projectId;
}
public List<ProjectLevel1Repository> getProjectlevel1() {
return projectlevel1;
}
public void setProjectlevel1(List<ProjectLevel1Repository> projectlevel1) {
this.projectlevel1 = projectlevel1;
}
and
package ma.eurnet.mp.tables.model;
#JsonAutoDetect
#Entity
#SequenceGenerator(name = "projectLevel1Sequence", sequenceName = "project_level1_t_projectlevel1pk_seq", allocationSize = 1)
#Table(name="project_level1_t")
public class ProjectLevel1Repository implements Serializable {
private static final long serialVersionUID = 1L;
public ProjectLevel1Repository() {
}
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "projectLevel1Sequence")
#Column(name = "projectlevel1id")
private Long projectLevel1Id;
#ManyToOne
#JoinColumn(name="projectid", referencedColumnName = "projectid")
#JsonIgnore
private ProjectRepository project;
#OneToMany(fetch = FetchType.EAGER, mappedBy="projectlevel1id")
#JsonIgnore
private List<ProjectLevel2Repository> projectlevel2 = new ArrayList<ProjectLevel2Repository>();
public List<ProjectLevel2Repository> getProjectlevel2() {
return projectlevel2;
}
public Long getProjectLevel1Id() {
return projectLevel1Id;
}
public void setProjectLevel1Id(Long projectLevel1Id) {
this.projectLevel1Id = projectLevel1Id;
}
public ProjectRepository getProject() {
return project;
}
public void setProject(ProjectRepository project) {
this.project = project;
}
}
And
package ma.eurnet.mp.tables.model;
import java.io.Serializable;
#JsonAutoDetect
#Entity
#SequenceGenerator(name = "projectLevel2Sequence", sequenceName = "project_level2_t_projectlevel2_seq", allocationSize = 1)
#Table(name="project_level2_t")
public class ProjectLevel2Repository implements Serializable {
private static final long serialVersionUID = 1L;
public ProjectLevel2Repository() {
}
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "projectLevel2Sequence")
#Column(name = "projectlevel2id")
private Long projectLevel2Id;
#Column(name = "levelname")
private String levelName;
#Column(name = "created_by")
private String createdBy;
#Column(name = "creation_date")
private String creationDate;
#ManyToOne
#JoinColumn(name="projectlevel1id", referencedColumnName = "projectlevel1id")
#JsonIgnore
private ProjectRepository projectlevel1id;
public Long getProjectLevel2Id() {
return projectLevel2Id;
}
public void setProjectLevel2Id(Long projectLevel2Id) {
this.projectLevel2Id = projectLevel2Id;
}
public String getLevelName() {
return levelName;
}
public void setLevelName(String levelName) {
this.levelName = levelName;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getCreationDate() {
return creationDate;
}
public void setCreationDate(String creationDate) {
this.creationDate = creationDate;
}
public ProjectRepository getProjectlevel1id() {
return projectlevel1id;
}
public void setProjectlevel1id(ProjectRepository projectlevel1id) {
this.projectlevel1id = projectlevel1id;
}
}
but when I run my application I get this error
org.hibernate.MappingException: Unable to find column with logical name: projectlevel1id in org.hibernate.mapping.Table(project_t) and its related supertables and secondary tables
how can I fix this please
In ProjectLevel2Repository you have a mapping towards ProjectRepository using a #JoinColumn named projectlevel1id which doesn't exist. From what you describe, this should be mapped to ProjectLevel1Repository
#ManyToOne
#JoinColumn(name="projectlevel1id", referencedColumnName = "projectlevel1id")
#JsonIgnore
private ProjectLevel1Repository projectlevel1;
I have 5 tables every table has relation one to many with the next table
Project_t -> project_level1_t -> project_level2_t -> project_level3_t -> project_level4_t
I want to user hibernate with these tables
CREATE TABLE project_t
(
projectid serial NOT NULL,
address1 character varying(128),
postcode character varying(7),
city character varying(64),
level_four_name character varying(128),
CONSTRAINT project_t_pkey PRIMARY KEY (projectid),
CONSTRAINT projectcode_unique UNIQUE (projectcode)
)
And project_level1_t
CREATE TABLE project_level1_t
(
projectlevel1id integer NOT NULL DEFAULT nextval('project_level1_t_projectlevel1pk_seq'::regclass),
levelname character varying(256),
projectid integer,
CONSTRAINT project_level1_t_pkey PRIMARY KEY (projectlevel1id),
CONSTRAINT project_level1_t_project_t_fkey FOREIGN KEY (projectid)
REFERENCES project_t (projectid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
And project_level2_t
CREATE TABLE project_level2_t
(
projectlevel2id integer NOT NULL DEFAULT nextval('project_level2_t_projectlevel2_seq'::regclass),
levelname character varying(256),
projectlevel1id integer,
CONSTRAINT project_level2_t_pkey PRIMARY KEY (projectlevel2id),
CONSTRAINT project_level2_t_projec_level_1_fkey FOREIGN KEY (projectlevel1id)
REFERENCES project_level1_t (projectlevel1id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
And this is the Repository files
package ma.eurnet.mp.tables.model;
import javax.persistence.GenerationType;
#JsonAutoDetect
#Entity
#Table(name = "project_t")
public class ProjectRepository implements Serializable {
private static final long serialVersionUID = 1L;
public ProjectRepository() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "projectid")
private Long projectId;
#OneToMany(fetch = FetchType.EAGER, mappedBy="project")
#JsonIgnore
private List<ProjectLevel1Repository> projectlevel1 = new ArrayList<ProjectLevel1Repository>();
public Long getProjectId() {
return projectId;
}
public void setProjectId(Long projectId) {
this.projectId = projectId;
}
public List<ProjectLevel1Repository> getProjectlevel1() {
return projectlevel1;
}
public void setProjectlevel1(List<ProjectLevel1Repository> projectlevel1) {
this.projectlevel1 = projectlevel1;
}
and
package ma.eurnet.mp.tables.model;
#JsonAutoDetect
#Entity
#SequenceGenerator(name = "projectLevel1Sequence", sequenceName = "project_level1_t_projectlevel1pk_seq", allocationSize = 1)
#Table(name="project_level1_t")
public class ProjectLevel1Repository implements Serializable {
private static final long serialVersionUID = 1L;
public ProjectLevel1Repository() {
}
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "projectLevel1Sequence")
#Column(name = "projectlevel1id")
private Long projectLevel1Id;
#ManyToOne
#JoinColumn(name="projectid", referencedColumnName = "projectid")
#JsonIgnore
private ProjectRepository project;
#OneToMany(fetch = FetchType.EAGER, mappedBy="projectlevel1id")
#JsonIgnore
private List<ProjectLevel2Repository> projectlevel2 = new ArrayList<ProjectLevel2Repository>();
public List<ProjectLevel2Repository> getProjectlevel2() {
return projectlevel2;
}
public Long getProjectLevel1Id() {
return projectLevel1Id;
}
public void setProjectLevel1Id(Long projectLevel1Id) {
this.projectLevel1Id = projectLevel1Id;
}
public ProjectRepository getProject() {
return project;
}
public void setProject(ProjectRepository project) {
this.project = project;
}
}
And
package ma.eurnet.mp.tables.model;
import java.io.Serializable;
#JsonAutoDetect
#Entity
#SequenceGenerator(name = "projectLevel2Sequence", sequenceName = "project_level2_t_projectlevel2_seq", allocationSize = 1)
#Table(name="project_level2_t")
public class ProjectLevel2Repository implements Serializable {
private static final long serialVersionUID = 1L;
public ProjectLevel2Repository() {
}
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "projectLevel2Sequence")
#Column(name = "projectlevel2id")
private Long projectLevel2Id;
#Column(name = "levelname")
private String levelName;
#Column(name = "created_by")
private String createdBy;
#Column(name = "creation_date")
private String creationDate;
#ManyToOne
#JoinColumn(name="projectlevel1id", referencedColumnName = "projectlevel1id")
#JsonIgnore
private ProjectLevel1Repository projectlevel1id;
public Long getProjectLevel2Id() {
return projectLevel2Id;
}
public void setProjectLevel2Id(Long projectLevel2Id) {
this.projectLevel2Id = projectLevel2Id;
}
public String getLevelName() {
return levelName;
}
public void setLevelName(String levelName) {
this.levelName = levelName;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getCreationDate() {
return creationDate;
}
public void setCreationDate(String creationDate) {
this.creationDate = creationDate;
}
public ProjectRepository getProjectlevel1id() {
return projectlevel1id;
}
public void setProjectlevel1id(ProjectRepository projectlevel1id) {
this.projectlevel1id = projectlevel1id;
}
}
I want to save each entity by himself so if run this code
ProjectRepository projectRepository = projectService.getProjectById(Long.parseLong(projectId));
ProjectLevel1Repository projectLevel1Repository = new ProjectLevel1Repository();
projectLevel1Repository.setProject(projectRepository);
projectLevel1Repository.setLevelName(level1Name);
projectLevel1Service.saveOrUpdateRepository(projectLevel1Repository);
ProjectLevel2Repository projectLevel2Repository = new ProjectLevel2Repository();
projectLevel2Repository.setLevelName("Test Level 2");
projectLevel2Repository.setProjectlevel1id(projectLevel1Repository);
projectLevel2Service.saveOrUpdateRepository(projectLevel2Repository);
I want to save one projectLevel1 and one projectLevel2 but what is happening now two projectLevel1 save with one projectLevel2
I have Class Customer ,User , Customer has property manager of user class
Class Customer {
/** The manager. */
#ManyToOne(optional = false, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
#JoinColumn(name = "MANAGER")
#JsonSerialize(using = EntitySerializer.class)
#JsonDeserialize(using = UserDeserializer.class)
private User manager;
}
-------------------------------------
Class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = User.TABLE_NAME + "_SEQUENCE")
#SequenceGenerator(name = User.TABLE_NAME + "_SEQUENCE", sequenceName = User.TABLE_NAME + "_SEQ")
#Column(name = FIELD_ID, nullable = false)
#SuppressWarnings("PMD.ShortVariable")
private Integer id;
#Override
public Integer getId() {
return id;
}
#Override
public void setId(final Integer newId) {
//System.out.println("setID");
id = newId;
}
}
Now when i am trying to create criteria
final Criteria criteria = getSession().createCriteria(Customer.class);
criteria.add(Restrictions.ilike("manager", "%"+searchTerm+"%"))
It throwing Error :-
org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.User.id
Caused by:
java.lang.IllegalArgumentException: Can not set java.lang.Integer field com.User.id to java.lang.String
**Id field is integer **
Could you please change the following:
final Criteria criteria = getSession().createCriteria(Customer.class); criteria.add(Restrictions.ilike("manager", "%"+searchTerm+"%"))
by the following:
final Criteria criteria = getSession().createCriteria(Customer.class); criteria.add(Restrictions.ilike("manager.name", "%"+searchTerm+"%"))
LIKE clause is applicable to text column only.
this code to used
return this.sessionFactory.getCurrentSession()
.createCriteria(UserTraining.class)
.add(Restrictions.eq("userProfile.userId", userId))
.list();
You used this annotation to error remove
#Table(name="user_training")
#Entity
public class UserTraining {
#Id
#GeneratedValue
#Column(name="id")
private int id;
//Generate getter setter of id
/*
#Column(name="user_id")
private int userId;
*/
#JsonIgnore
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name = "user_id")
private UserProfile userProfile;
public UserProfile getUserProfile() {
return userProfile;
}
public void setUserProfile(UserProfile userProfile) {
this.userProfile = userProfile;
}
#OneToOne
#JoinColumn(name = "training_id")
private Training training;
#Column(name="view_count")
private int viewCount;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Training getTraining() {
return training;
}
public void setTraining(Training training) {
this.training = training;
}
public int getViewCount() {
return viewCount;
}
public void setViewCount(int viewCount) {
this.viewCount = viewCount;
}
}
i would use a ModelBase with an ID and a Timestamp for every class/entity. But when i user the Long type for the Primary Key in the JPARepository<> interface i get the message
Not an entity: class java.lang.Long
Code:
#MappedSuperclass
public class ModelBase implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false, columnDefinition = "datetime")
private Date lastModified;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getLastModified() {
return lastModified;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
#PreUpdate
#PrePersist
public void updateLastModified() {
lastModified = new Date();
}
}
Modelclass inheritanced from Modelbase
#Entity
#Table(name = "Name")
public class Name extends ModelBase implements Serializable {}
Repo
public interface NameRepository extends JpaRepository<Long, Name>{}
what am i doing wrong?
thanks
It's backwards:
JpaRepository<Name, Long>
First the entity, then the ID. Check JPARepository javadoc.