I have two classes cards and tags. I want a many to many relationship between them and store the cardId and tagId in one table. When i create the database from the code it creates 2 different table with one to many relationship. tag_cards and card_tags. What am i doing wrong here? I want one single table with many to many relationship.
import javax.faces.bean.ManagedBean;
import javax.persistence.*;
import java.util.Set;
#ManagedBean(name = "addToCardBean")
#javax.persistence.Table(name = "cards")
#Entity
public class Card implements java.io.Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public int id;
#Column(name="username",nullable = false)
private String username;
#Column(name="text",nullable = false)
private String text;
#Column(name="author")
private String author;
#Column(name="title")
private String title;
#Column (name="source")
private String source;
#Column(name="facebookID" ,columnDefinition="BigInt(20) default '0'")
private long facebookID;
#ElementCollection(targetClass = Tag.class)
private Set<Tag> tags;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public long getFacebookID() {
return facebookID;
}
public void setFacebookID(long facebookID) {
this.facebookID = facebookID;
}
#ManyToMany(mappedBy = "cards")
public Set<Tag> getTags() {
return tags;
}
public void setTags(Set<Tag> tags) {
this.tags = tags;
}
}
import javax.faces.bean.ManagedBean;
import javax.persistence.*;
import java.util.Set;
#Entity
#Table(name="tag")
#ManagedBean(name="tagBean")
public class Tag implements java.io.Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer id;
#Column(name = "tagName", nullable = false)
private String tagName;
#ElementCollection(targetClass = Card.class)
private Set<Card> cards;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTagName() {
return tagName;
}
public void setTagName(String tagName) {
this.tagName = tagName;
}
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(
name = "cards_tags",
joinColumns = #JoinColumn(name = "id"),
inverseJoinColumns = #JoinColumn(name = "id")
)
public Set<Card> getCards() {
return cards;
}
public void setCards(Set<Card> cards) {
this.cards = cards;
}
}
You are facing this issue because you have used the annotations both at the field and method(getter) level i.e you have mixed both.
#Column(name = "tagName", nullable = false)
private String tagName;
and
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(
name = "cards_tags",
joinColumns = #JoinColumn(name = "id"),
inverseJoinColumns = #JoinColumn(name = "id")
)
public Set<Card> getCards() {
return cards;
}
You have to either use them only on field or only on method(getter). Do not mixup the two.
Why you are ending up with two tables is because the field annotations are getting considered and the many to many mapping is on the getter method which is not being considered.
One way is just use at field level. If annotating at field, change to the following(you need to modify the other entity class as well):
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(
name = "cards_tags",
joinColumns = #JoinColumn(name = "id"),
inverseJoinColumns = #JoinColumn(name = "id")
)
#ElementCollection(targetClass = Card.class)
private Set<Card> cards;
You need to make changes in both classes. Move the annotations from getter to field as described above. Or you have to make changes so that all annotations are on getter instead of field.
Additional links:
https://softwareengineering.stackexchange.com/questions/258541/where-to-put-jpa-annotations-field-or-getter
the difference between anotating a field and its getter method JPA
Related
I am trying to add multiple entities in a single entity, I don't know this way possible or not please refer to my below code and help
the below code are the entity tables
#Entity
#Table(name = "agent_employee")
public class AgentEmployee extends Agent implements Serializable{
private static final long serialVersionUID = 1L;
#OneToMany // unidirectional
#JoinColumn(name = "employment_id", referencedColumnName = "id")
List<Employment> employmnet = new ArrayList<Employment>();
#OneToMany(
mappedBy = "agent",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private Set<Officess> officess = new HashSet<>();
public List<Employment> getEmploymnet() {
return employmnet;
}
public void setEmploymnet(List<Employment> employmnet) {
this.employmnet = employmnet;
}
public Set<Officess> getOfficess() {
return officess;
}
public void setOfficess(Set<Officess> officess) {
this.officess = officess;
}
}
and Employment class is
#Data
#Entity
public class Employment {
#Id
#Column(nullable = false, unique = true)
private Long id;
private String empName;
private String location;
#Override
public String toString() {
return "Employment [id=" + id + ", empName=" + empName + ", location=" + location + "]";
}
}
and Offices class is
#Data
#Entity
#Table(name = "officess")
public class Officess implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String officeName;
#ManyToOne
#JoinColumn(name = "agent_emp")
private AgentEmployee agent;
}
And I have used spring boot repositories to all the respective entities
#GetMapping(path = "/add")
public #ResponseBody String addAgentEmployee() {
try {
AgentEmployee agemp = new AgentEmployee();
agemp.setFirstName("harish");
agemp.setLastName("kadsuru");
agemp.setEmail("hari**********is.net");
Employment emp1 = new Employment();
Employment emp2 = new Employment();
Employment emp3 = new Employment();
emp1.setId(501l);
emp2.setId(502l);
emp3.setId(503l);
emp1.setEmpName("junior engineer");
emp2.setEmpName("senior engineer");
emp3.setEmpName("team leader");
emp1.setLocation("bengaluru");
emp2.setLocation("mumbai");
emp3.setLocation("UAE");
List<Employment> emps = Arrays.asList(emp1, emp2, emp3);
employmentRepository.saveAll(emps);
agemp.setEmploymnet(emps);
agentEmployeeRepository.save(agemp);
return "saved";
} catch (Exception e) {
return "unable to save data due to exception";
}
}
#GetMapping("addOffice")
public #ResponseBody String addAgentEmployeeOffice() {
AgentEmployee emp;
Optional<AgentEmployee> agemp = agentEmployeeRepository.findById(27l);
if (agemp.isPresent()) {
emp = agemp.get();
}
else {
emp =new AgentEmployee();
emp.setFirstName("garish");
emp.setLastName("tumkur");
emp.setEmail("garish.kr#cyclotis.net");
}
log.info("###### {}",agemp);
Officess off1 = new Officess();
Officess off2 = new Officess();
Officess off3 = new Officess();
off1.setOfficeName("Google");
off2.setOfficeName("facebook");
off3.setOfficeName("Instagram");
Set<Officess> offices = emp.getOfficess();
offices.add(off1);
offices.add(off2);
offices.add(off3);
agentEmployeeRepository.save(emp);
log.info("######## {}", offices);
return "saved";
}
I don't think any problem with code, but I think I have a problem while saving the data. Kindly any body refer the correct way to analyse this problem.
Looks like your mapping is not correct. Also verify you have a EMPID column.
You don't need to use the #JoinTable annotation in your case.
As you are saving data you should use #PostMapping
StatusReport - removed private BigInteger EMPID; as it is used in joining
#Entity
#Table(name="statusreport")
public class StatusReport {
private BigInteger COMPLIANCEID;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger STATUSRPTID;
private String COMMENTS;
private Date CREATEDDATE;
private BigInteger DEPARTMENT_ID;
#OneToOne
#JoinColumn(name = "EMPID")
private Employees employee;
//others methods
}
Employee - removed private BigInteger DEPARTMENT_ID; as it is used in joining
#Entity
public class Employees {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger EMPID;
private String FIRSTNAME;
private String LASTNAME;
private Date DOB;
private String EMAIL;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID")
private Department department;
//others methods
}
below is my stores enitity
#Entity
#Table(name="stores")
public class Stores {
#Id
#GeneratedValue
private Long id;
#Column(name ="incharge_id")
private Integer inchargeId;
#Column(name = "store_name")
private String storeName;
#OneToMany(mappedBy = "stores",
fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private Set<Items> items;
public Set<Items> getItems() {
return items;
}
public void setItems(Set<Items> items) {
this.items = items;
for (Items item : items) {
item.setStores(this);
}
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getInchargeId() {
return inchargeId;
}
public void setInchargeId(Integer inchargeId) {
this.inchargeId = inchargeId;
}
public String getStoreName() {
return storeName;
}
public void setStoreName(String storeName) {
this.storeName = storeName;
}
}
Below is my item entity
package bt.gov.dit.inventoryservice.model;
import javax.persistence.*;
import java.util.Date;
#Entity
#Table(name = "items")
public class Items {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
#Column(name="item_name")
private String itemName;
#ManyToOne
private Categories categories;
#ManyToOne(fetch = FetchType.LAZY)
//#JoinColumn(name = "book_category_id", referencedColumnName = "id")
#JoinColumn(name = "stores_id", nullable = false,referencedColumnName = "id")
private Stores stores;
#Column(name="insert_date")
private Date insertDate;
#Column(name="update_date")
private Date updateDate;
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Categories getCategories() {
return categories;
}
public void setCategories(Categories categories) {
this.categories = categories;
}
public Stores getStores() {
return stores;
}
public void setStores(Stores stores) {
this.stores = stores;
stores.getItems().add(this);
}
public Date getInsertDate() {
return insertDate;
}
public void setInsertDate(Date insertDate) {
this.insertDate = insertDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
}
I have one-to-many relationship between them. One store can have many items. But I don't know how to insert items with stores . I have tried the default save of Jpa respoistory but in place of stores_id (which is the foreign key) it saves null. Can anyone tell me how to implement the service?
It will be something like below.
Stores stores = new Stores();
stores.setStoreName("store name");
// Set other fields of store entity
Item item1 = new Item();
item1.setItemName("item name 1");
// Set other fields of item entity
Item item2 = new Item();
item2.setItemName("item name 2");
// Set other fields of item entity
// Call setItems
// Call getItems in a Set class object like Set<Item> items;
stores.setItems(items);
storesService.save(stores); // it will save all items with foreign key.
Pardon me if this looks too basic, I am just a beginner in springboot. I am trying to create a simple project. I have entity class "company.java" and another "jobs.java"
I have already mapped them such that it will be saving both "companyID,jobID"
now my question is here :
1) how can I ensure that the record is captured into that new table when i feed data from thymeleaf fields. I have tried a dummy entry and its saving jobs into the jobs table but its not capturing anything to insert into the joined table
2) How do I query such that it saves and also when I search a job by its ID it shows me the company.
#Entity
#Table(name = "company_account")
#EntityListeners(AuditingEntityListener.class)
#SecondaryTable(name = "company_profile")
public class CompanyAccount {
private int id;
private String CompanyName;
private String PhoneNumber;
private String Number_of_employees;
private String CompanyURL;
private String OrganisationType;
private String PrimaryIndustry;
private byte[] Logo;
private String Location;
private String DateEstablished;
private String Headquarters;
private String SocialMedia;
public CompanyAccount() {
}
///////////////////////here i tried the mapping
#OneToMany(fetch = FetchType.LAZY, mappedBy = "company_account")
private List<NewJobs> jobs = new ArrayList<NewJobs>();
#Id
// #org.hibernate.annotations.ColumnDefault("001")
#GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//////////////////////////////////
deleted the getters and setters
///////////////////////////////////////////////////////////////
#Entity
#Table(name = "newjobs")
#EntityListeners(AuditingEntityListener.class)
public class NewJobs {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#org.hibernate.annotations.ColumnDefault("001")
private int newjobid;
public NewJobs() {
}
tried my mapping here
#ManyToOne(fetch = FetchType.LAZY)
// #JoinColumn(name = "company_account")
#JoinTable(name = "company_jobs", joinColumns = { #JoinColumn(name = "id") }, inverseJoinColumns = {
#JoinColumn(name = "newjobid") })
private CompanyAccount CompanyAccount;
}
How can I query my insert and also my search by id ?
The relationships works fine, the tables are created and the data is inserted correctly. But when page loads in browser, many to many relationships doesn't shown.
But professions are not null:
Here is my entities:
#Entity
#Table(name = "users")
public class User {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "login", nullable = true, length = 50)
private String login;
#Column(name = "pass", nullable = true, length = 50)
private String password;
#Column(name = "name", nullable = false, length = 50)
private String name;
....
public User() {
}
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name="worker_profession", joinColumns =#JoinColumn(name="id_user", referencedColumnName="id"),
inverseJoinColumns = #JoinColumn(name="id_profession", referencedColumnName="id")
)
private Set<Profession> profession;
public Set<Profession> getProfession() {
return profession;
}
public void setProfession(Set<Profession> profession) {
this.profession = profession;
}
...
}
And:
#Entity
#Table(name = "profession")
public class Profession {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name = "profession_name", nullable = false, length = 50)
private String professionName;
public Profession() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getProfessionName() {
return professionName;
}
public void setProfessionName(String professionName) {
this.professionName = professionName;
}
#ManyToMany(fetch = FetchType.EAGER, mappedBy = "profession")
private Set<User> users;
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
in UserController.class I have:
#RestController
#RequestMapping("/user")
public class UserController {
#Autowired
private UserRepository userRepository;
#RequestMapping(value = "", method = RequestMethod.GET)
#ResponseBody
public List<User> getAllUsers() {
return userRepository.findAll();
}
...
}
So, where is my mistake? Thanks.
I have the following entities defined:
Restaurante:
#Entity
#Table(name = "restaurantes")
public class Restaurante implements Serializable {
private int id;
private Set<Menu> menus = new HashSet<>(0);
public Restaurante() {
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "restaurante_id", unique = true, nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#JsonIgnore
#OneToMany(mappedBy = "restaurante")
public Set<Menu> getMenus() {
return menus;
}
public void setMenus(Set<Menu> menus) {
this.menus = menus;
}
}
And menu:
#Entity
#Table(name = "menus")
public class Menu implements Serializable {
private int id;
private Restaurante restaurante;
public Menu() {
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "menu_id", unique = true, nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#JsonIgnore
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "restaurante_id", nullable = false)
public Restaurante getRestaurante() {
return restaurante;
}
public void setRestaurante(Restaurante Restaurante) {
this.restaurante = restaurante;
}
}
And when I perform the following query:
public Menu getMenuById(Integer id) throws HibernateException, IndexOutOfBoundsException {
session = HibernateSessionService.getSessionFactory().openSession();
criteria = session.createCriteria(Menu.class)
.add(Restrictions.eq("id", id));
return (Menu) criteria.list().get(0);
}
The property restaurante is null.
There is a restaurante loaded in the database with the Id I'm using, and there are several menus loaded with that foreign key as well.
Can someone give me advice or help me?
Thanks in advance!