Add row to join table using JPA - jpa

I'm using JPA 2.0 and I'm using a generated schema.
Here is my mapping:
#Entity
#Table(name = "CBV_USER")
public class CbvUser implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#Column(name = "Login")
private String login;
#Basic(optional = false)
#Column(name = "Password")
private String password;
#Basic(optional = false)
#Column(name = "Email")
private String email;
#Basic(optional = false)
#Column(name = "FirstName")
private String firstName;
#Basic(optional = false)
#Column(name = "LastName")
private String lastName;
#Basic(optional = false)
#Column(name = "Id")
private String id;
#Column(name = "Score")
private BigDecimal score;
#JoinTable(name = "FRIENDSHIP", joinColumns = {
#JoinColumn(name = "Login0", referencedColumnName = "Login")}, inverseJoinColumns = {
#JoinColumn(name = "Login1", referencedColumnName = "Login")})
#ManyToMany
private List<CbvUser> cbvUserList2;
#ManyToMany(mappedBy = "cbvUserList2")
private List<CbvUser> cbvUserList3;
public CbvUser() {
}
public CbvUser(String login) {
this.login = login;
}
public CbvUser(String login, String password, String email, String firstName, String lastName, String id) {
this.login = login;
this.password = password;
this.email = email;
this.firstName = firstName;
this.lastName = lastName;
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public BigDecimal getScore() {
return score;
}
public void setScore(BigDecimal score) {
this.score = score;
}
public List<CbvUser> getCbvUserList2() {
return cbvUserList2;
}
public void setCbvUserList2(List<CbvUser> cbvUserList2) {
this.cbvUserList2 = cbvUserList2;
}
public List<CbvUser> getCbvUserList3() {
return cbvUserList3;
}
public void setCbvUserList3(List<CbvUser> cbvUserList3) {
this.cbvUserList3 = cbvUserList3;
}
#Override
public int hashCode() {
int hash = 0;
hash += (login != null ? login.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof CbvUser)) {
return false;
}
CbvUser other = (CbvUser) object;
if ((this.login == null && other.login != null) || (this.login != null && !this.login.equals(other.login))) {
return false;
}
return true;
}
#Override
public String toString() {
return "models.CbvUser[login=" + login + "]";
}
}
My problem is that I can't figure out how to add a new row in the Join Table FRIENDSHIP through a specific CbvUser or through an EntityManager.
I'll be really grateful for any help.

Something like this should work:
CbvUser user1 = new CbvUser();
...
CbvUser user2 = new CbvUser();
...
// declare user2 as a friend of user1
List<CbvUser> cbvUserList2 = new ArrayList<CbvUser>();
cbvUserList2.add(user2);
user1.setCbvUserList2(cbvUserList2);
// declare user1 as a friend of user2
List<CbvUser> cbvUserList3 = new ArrayList<CbvUser>();
cbvUserList3.add(user1);
user2.setCbvUserList3(cbvUserList3);
em.persist(user1);
em.persist(user2);
em.flush();
The friendship relation is a (self-referencing) bidirectional association, so you must set both sides of the link correctly (from user1 to user2 and from user2 to user1).

Providing a public add/remove that maintains referential integrity might be even more elegant here.

Related

JPA- insert a ID of parent to child table

when there is a many to one associate between two object in hibernate(JPA) and we want insert a ID of parent to child table without new record in parent table how do I implement it?
#ManyToOne(targetEntity = RoleEntity.class,cascade = CascadeType.ALL,fetch = FetchType.LAZY)
#JoinColumn(name = "FK_ROLE_ID",referencedColumnName = "ID")
private RoleEntity role;
I write this:
UserEntity userEntity=new UserEntity();
userEntity.setUserName(username);
userEntity.setPassword(password);
userEntity.setCreatedDate(new Date().toString());
RoleEntity roleEntity=new RoleEntity();
roleEntity.setTitle("user");
userEntity.setRole(roleEntity);
but the last three line also insert a new record in user table.
This completely of roleEntity:
package Entity;
import javax.persistence.*;
import java.io.Serializable;
/**
* Created by Mohsen on 7/10/2018.
*/
#Entity(name = "role")
#Table(name = "ROLE")
public class RoleEntity implements Serializable {
#Id
#Column(name = "ID")
#SequenceGenerator(name = "SEQ_ROLE", sequenceName = "SEQ_ROLE", allocationSize = 1)
#GeneratedValue(generator = "SEQ_ROLE", strategy = GenerationType.SEQUENCE)
private int id;
#Basic
#Column(name = "Title")
private String title;
// #OneToMany(targetEntity = UserEntity.class,cascade = CascadeType.ALL,fetch = FetchType.LAZY)
// #JoinColumn(name = "FK_ROLE_ID",referencedColumnName = "ID")
// private Set<UserEntity> user;
public RoleEntity() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
This completely of userEntity:
package Entity;
import javax.persistence.*;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Mohsen on 7/10/2018.
*/
#Entity(name = "user")
#Table(name = "USERR")
public class UserEntity implements Serializable {
#Id
#Column(name = "ID")
#SequenceGenerator(name = "SEQ_USER", allocationSize = 1, sequenceName = "SEQ_USER")
#GeneratedValue(generator = "SEQ_USER", strategy = GenerationType.SEQUENCE)
private int id;
#Basic
#Column(name = "UserName", columnDefinition = "VARCHAR2(20 CHAR)")
private String userName;
#Basic
#Column(name = "Password", columnDefinition = "VARCHAR2(255 CHAR)")
private String password;
#Basic
#Column(name = "CreatedDate")
private String createdDate;
#Basic
#Column(name = "EndedDate")
private String endedDate;
#OneToOne(targetEntity = PeopleEntity.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private PeopleEntity people;
#ManyToOne(targetEntity = RoleEntity.class,cascade = CascadeType.ALL,fetch = FetchType.LAZY)
#JoinColumn(name = "FK_ROLE_ID",referencedColumnName = "ID")
private RoleEntity role;
public RoleEntity getRole() {
return role;
}
public void setRole(RoleEntity role) {
this.role = role;
}
public UserEntity() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getEndedDate() {
return endedDate;
}
public void setEndedDate(String endedDate) {
this.endedDate = endedDate;
}
public PeopleEntity getPeople() {
return people;
}
public void setPeople(PeopleEntity people) {
this.people = people;
}
}
I have found the solution
I set cascade = CascadeType.REMOVE in child object and it works

Merge 3 Tables into 1 SpringBoot + Postgres

I have an Application written in spring boot with 3 Tables T1, T2 and T3 on Postgres
t1 one2many mapping with t2 and t2 one2many with t3
How can I merge these tables into one? Do the model and repository still stay the same?
Model for T1
#Entity
#Table(name = "maintenance_type")
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = { "createdAt", "updatedAt" }, allowGetters = true)
public class MaintenanceType implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotBlank
#Column(unique=true)
private String changeType;
#Column(nullable = false, updatable = false)
#Temporal(TemporalType.TIMESTAMP)
#CreatedDate
private Date createdAt;
#Column(nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#LastModifiedDate
private Date updatedAt;
#OneToMany(mappedBy = "maintenanceType", cascade = CascadeType.ALL)
private Set<TierTwoQuestion> tierTwoQuestion;
public MaintenanceType() {
}
public MaintenanceType(Long id, String changeType) {
super();
this.id = id;
this.changeType = changeType;
}
public MaintenanceType(String changeType) {
super();
this.changeType = changeType;
}
public Set<TierTwoQuestion> getTierTwoQuestion() {
return tierTwoQuestion;
}
//
public void setTierTwoQuestion(Set<TierTwoQuestion> tierTwoQuestion) {
this.tierTwoQuestion = tierTwoQuestion;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getChangeType() {
return changeType;
}
public void setChangeType(String changeType) {
this.changeType = changeType;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
}
Model for T2
#Entity
#Table(name = "tier_two_question")
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = { "createdAt", "updatedAt" }, allowGetters = true)
public class TierTwoQuestion implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotBlank
#Column(unique=true)
private String question;
#ManyToOne
#JoinColumn(name = "maintenanceId", nullable = false)
private MaintenanceType maintenanceType;
#OneToMany(mappedBy = "tierTwoQuestion", cascade = CascadeType.ALL)
private Set<TierThreeQuestion> tierThreeQuestion;
#Column(nullable = false, updatable = false)
#Temporal(TemporalType.TIMESTAMP)
#CreatedDate
private Date createdAt;
#Column(nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#LastModifiedDate
private Date updatedAt;
public TierTwoQuestion() {
}
public TierTwoQuestion(Long id) {
super();
this.id = id;
this.question = question;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
// public MaintenanceType getMaintenanceType() {
// return maintenanceType;
// }
public void setMaintenanceType(MaintenanceType maintenanceType) {
this.maintenanceType = maintenanceType;
}
public Set<TierThreeQuestion> getTierThreeQuestion() {
return tierThreeQuestion;
}
public void setTierThreeQuestion(Set<TierThreeQuestion> tierThreeQuestion) {
this.tierThreeQuestion = tierThreeQuestion;
}
}
I tried adding recreating the model with all T1 T2 T3 in one table but not working as expected

org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.SQLGrammarException: ERROR: column "----" of relation "-----" does not exist

I'm getting this error while storing an object into database using persistence API. For me, it looks alright. Couldn't find the issue anywhere in the model class.
Please let me know if you need any other info.
Thanks in advance.
Error:
SEVERE: Servlet.service() for servlet [Project] in context with path
[/Project] threw exception [Request processing failed; nested
exception is org.springframework.orm.jpa.JpaSystemException:
org.hibernate.exception.SQLGrammarException: ERROR: column
"first_name" of relation "users" does not exist Position: 36; nested
exception is javax.persistence.PersistenceException:
org.hibernate.exception.SQLGrammarException: ERROR: column
"first_name" of relation "users" does not exist Position: 36] with
root cause org.postgresql.util.PSQLException: ERROR: column
"first_name" of relation "users" does not exist Position: 36 at
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
at
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
......
User.java
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
#Column(unique = true, nullable = false)
private String email;
#Column(nullable = false)
private String password;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column( name = "phone" )
private String phone;
#OneToMany(targetEntity=Address.class, mappedBy="user",cascade=CascadeType.ALL)
private List<Address> address;
private boolean enabled;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
#ElementCollection
#CollectionTable(name = "authorities",
joinColumns = #JoinColumn(name = "user_id" ) )
#Column( name = "role" )
private Set<String> roles;
#Transient
private String password2;
public User()
{
roles = new HashSet<String>();
enabled=true;
}
public boolean isAdmin()
{
return roles.contains( "ROLE_ADMIN" );
}
public boolean isUser()
{
return roles.contains( "ROLE_USER" );
}
public Long getId()
{
return id;
}
public void setId( Long id )
{
this.id = id;
}
public String getEmail()
{
return email;
}
public void setEmail( String email )
{
this.email = email;
}
public String getPassword()
{
return password;
}
public void setPassword( String password )
{
this.password = password;
}
public String getFirstName()
{
return firstName;
}
public void setFirstName( String firstName )
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName( String lastName )
{
this.lastName = lastName;
}
public String getPhone()
{
return phone;
}
public void setPhone( String phone )
{
this.phone = phone;
}
public Set<String> getRoles()
{
return roles;
}
public void setRoles( Set<String> roles )
{
this.roles = roles;
}
public String getPassword2()
{
return password2;
}
public void setPassword2( String password2 )
{
this.password2 = password2;
}
}
Database:
create table users (
id int8 not null,
email varchar(255) not null unique,
enabled boolean not null,
first_name varchar(255),
last_name varchar(255),
password varchar(255) not null,
phone varchar(255),
primary key (id)
);
Controller:
#RequestMapping(value = "user/registration.html", method = RequestMethod.POST)
public String registrationPOST(#ModelAttribute User user, ModelMap models, SessionStatus sessionStatus)
{
user.setEnabled(false);
user = userDao.saveUser(user);
sessionStatus.setComplete();
models.put("status","Check your email to confirm your account");
return "user/registration";
}

JPA data retreival issue on webshpehre liberty and jax-rs 2.0

Here is my entity class
#Entity
#Table( name = "NEO_TEAM", schema = "METRICS" )
public class ETeam implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="ID")
private int id;
#Column(name="NAME")
private String name;
#Column(name="DESCRIPTION")
private String description;
//bi-directional many-to-one association to ETeamQueue
#OneToMany(mappedBy="eteam" , fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<ETeamQueue> teamQueue;
public ETeam(int id,String name,String description){
this.id = id;
this.name = name;
this.description = description;
}
public ETeam(String name,String description){
this.name = name;
this.description = description;
}
public ETeam() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public List<ETeamQueue> getTeamQueue() {
return this.teamQueue;
}
public void setTeamQueue(List<ETeamQueue> teamQueue) {
this.teamQueue = teamQueue;
}
public ETeamQueue addTeamQueue(ETeamQueue teamQueue) {
getTeamQueue().add(teamQueue);
teamQueue.setEteam(this);
return teamQueue;
}
public ETeamQueue removeTeamQueue(ETeamQueue teamQueue) {
getTeamQueue().remove(teamQueue);
teamQueue.setEteam(null);
return teamQueue;
}
}
And My REST call and JPQL query is
#Path("team")
#Produces(MediaType.APPLICATION_JSON)
public class TeamResource {
TeamService ts = new TeamService();
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public List<ETeam> listTeam(#PathParam("id") int id){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("NeoMetrics");
EntityManager em = emf.createEntityManager();
Query query = em.createQuery("select e from ETeam e where e.id = :id ",ETeam.class);
query.setParameter("id", id);
List<ETeam> lis = (List<ETeam>) query.getResultList();
//List<ETeam> lis = ts.getTeam(id);
return lis;
}
i want to fetch only one record from the team table but it give me result like shown in picture , which show the result is looped thousand times , its very long output result i only put part of it , any help will be really appreciated

What is root path in QueryDSL? Can you explain with an example?

I have the following two entity classes: Country and Type
#Entity
#Table(name = "countries")
public class Country {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id ;
#Column(name = "iso_code")
private String isoCode;
public Country() {
}
public Country(String isoCode) {
this.isoCode = isoCode;
}
public Country(int id, String isoCode) {
this.id = id;
this.isoCode = isoCode;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getIsoCode() {
return isoCode;
}
public void setIsoCode(String isoCode) {
this.isoCode = isoCode;
}
#Override
public String toString() {
return "Country{" +
"id=" + id +
", isoCode='" + isoCode + '\'' +
'}';
}
}
#Entity
#Table(name = "types")
public class Type {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "type")
private String type;
#ManyToOne
#JoinColumn(name = "country_id")
private Country country;
#ManyToOne
#JoinColumn(name = "group_id")
private Group group;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Group getGroup() {
return group;
}
public void setGroup(int priority) {
this.group = group;
}
}
I am trying to retrieve groups using the following in the repository class:
QType qType = QType.type1;
QCountry qCountry = QCountry.country;
QGroup qGroup = QGroup.group;
QGroup qGroup1 = qType.group;
JPAQuery queryGroup = new JPAQuery(em);
QueryBase queryBaseGroups = queryGroup.from(qGroup).innerJoin(qGroup1, qGroup).innerJoin(qType.country, qCountry);
However, I get the error -
java.lang.IllegalArgumentException: Undeclared path 'type1'. Add this path as a source to the query to be able to reference it.
New to JPA. What am I doing wrong here?
So this was solved by adding qType to the from function in the query.
QueryBase queryBaseGroups = queryGroup.from(qGroup, qType).innerJoin(qGroup1, qGroup).innerJoin(qType.country, qCountry);