In my program I realize a problem when it get a inheritance and a oneToMany relationship. That is:
I put to run. It will create the tables, without the foreign key. But when I remove the Inheritance annotations, and run again. It creates as foreign.
Class Employer
package com.example.TablePerConcreteClassExample.model;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="Employer")
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name="type")
#DiscriminatorValue(value="Employer")
public class Employer {
#Id
#Column (name = "empNo", nullable=false)
#GeneratedValue(strategy = GenerationType.AUTO)
private int empNo;
#Column(name = "name", nullable=false)
private String name;
#OneToMany (mappedBy = "employer",
fetch=FetchType.LAZY)
private List<Vehicle> vehicles;
public int getEmpNo() {
return empNo;
}
public void setEmpNo(int empNo) {
this.empNo = empNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Vehicle> getVehicles() {
return vehicles;
}
public void setVehicles(List<Vehicle> vehicles) {
this.vehicles = vehicles;
}
}
And Class Vehicle
package com.example.TablePerConcreteClassExample.model;
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;
#Entity
#Table(name="Vehicle")
public class Vehicle {
#Id
#Column (name = "id", nullable=false)
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "name", nullable=false)
private String name;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "empNo", nullable=false)
private Employer employer;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employer getEmployer() {
return employer;
}
public void setEmployer(Employer employer) {
this.employer = employer;
}
}
And my application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/TablePerConcreteClass?createDatabaseIfNotExist=true&useSSL=false&useTimezone=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=
spring.jpa.database=MYSQL
spring.datasource.platform=mysql
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.database.driverClassName=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.servlet.multipart.enabled=true
I expected a inheritance and in the vehicle table a Employer's foreign key.
The actual results are the inheritance, but no foreign key. But when I remove inheritance annotations, the foreing key will be created.
Related
I created two table and they are linked together by foreign key.
Table: users
Id name address_id
1 John 1
2 William 2
3 Scott 1
4 Mary 1
Table: Address
Id city
1 USA
2 Frank
This is Entity
User.java
package com.example.demo.model;
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;
#Table(name = "users")
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name")
private String name;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "address_id")
private Address address;
public User () {}
public User (String name) {
this.name=name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address.java
package com.example.demo.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Table(name = "address")
#Entity
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String city;
#OneToMany(mappedBy = "address", cascade = CascadeType.ALL)
private Set<User> users= new HashSet<>();
public Address () {}
public Address (String city) {
this.city=city;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
I have successfully created, modified, and deleted functions. I am trying to create a function to list the list by same value but still with no success. For example, if I want to list all "names" with address "1", it will output the values "John", "William", "Mary". I tried to use #Query but it also failed. Any suggestions or sample code for me? Thanks very much
I have 3 MySQL tables and I'm using them for Spring Security configuration with roles. And I want to populate 2 of them using RESTful.
User table:
Role table:
User_role table (this is the join table):
The app works successfully but at this moment I populate these tables from MySQL Workbench and I want to populate them using RESTful. But I don't know exactly how to do that, how the JSON object should look like when I do the POST request? For example the role table will be by default with these 2 values: ROLE_ADMIN and ROLE_USER, so I don't want to add any new value at this table, but how do I add a new user and populate the user table and the user_role table?
These are the entities:
User entity:
import java.util.List;
import javax.persistence.CascadeType;
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.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.JoinColumn;
#Entity
#Table(name = "appuser")
public class ApplicationUser {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private long id;
private String username;
private String password;
#ManyToMany(fetch = FetchType.EAGER,
cascade = {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH})
#JoinTable(name = "appuser_role",
joinColumns = #JoinColumn(name = "appuser_id"),
inverseJoinColumns = #JoinColumn(name = "approle_id"))
private List<Role> authorities;
public ApplicationUser() {
}
public long getId() {
return id;
}
public void setId(long 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 List<Role> getAuthorities() {
return authorities;
}
public void setAuthorities(List<Role> authorities) {
this.authorities = authorities;
}
}
Role entity:
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
#Table(name = "approle")
public class Role {
#Id
#Column(name = "role_id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
private String authority;
#JsonIgnore
#ManyToMany(mappedBy = "authorities")
private Set<ApplicationUser> users = new HashSet<>();
public Role() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
public Set<ApplicationUser> getUsers() {
return users;
}
public void setUsers(Set<ApplicationUser> users) {
this.users = users;
}
#Override
public String toString() {
return authority;
}
}
I am using spring-boot and hibernate. I am using one to many relationships.
In the main table, it has the details of the user logs like
jobId(pk), department, startDate. The child table is the category table(Id(pk),catId,catDesc,jobId(fk))
i.e each jobId in the parent table can have multiple categories. Now I want to get all the values from the main table and child table that exactly matches with the List of categories(child table values).
createQuery("select * from parent p, child c where p.jobId=c.jobId AND c.catId IN ("+catId+" ) )
here catId is a list of values. But I want to get only those values that match all the values and the query is dynamic.
package com.assorted.product.model;
import java.io.Serializable;
import java.util.Date;`enter code here`
import java.util.Set;
import javax.persistence.CascadeType;
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.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
#Table(name = "parent")
public class Parent implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
#Column(name = "JOB_ID")
private long jobId;
#Column(name = "USER_ID")
private String userId;
#Column(name = "COUNTRY_NAME")
private String countryName;
#Column(name = "DEPT_ID")
private long depId;
#Column(name = "DEPT_NAME")
private String depName;
#Column(name = "START_DATE")
#Temporal(TemporalType.DATE)
private Date startDate;
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#JoinColumn(name="JOB_ID",referencedColumnName="JOB_ID")
private Set<CategoryLogs> categoryLogs;
public long getJobId() {
return jobId;
}
public void setJobId(long jobId) {
this.jobId = jobId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public long getDepId() {
return depId;
}
public void setDepId(long depId) {
this.depId = depId;
}
public String getDepName() {
return depName;
}
public void setDepName(String depName) {
this.depName = depName;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Set<CategoryLogs> getCategoryLogs() {
return categoryLogs;
}
public void setCategoryLogs(Set<CategoryLogs> categoryLogs) {
this.categoryLogs = categoryLogs;
}
}
package com.assorted.product.model;
import javax.persistence.CascadeType;
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.Table;
#Entity
#Table(name = "child")
public class CategoryLogs {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
#Column(name = "ID")
private String id;
#Column(name = "CAT_ID")
private long catId;
#Column(name = "CAT_NAME")
private String catName;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "JOB_ID")
private Parent parent;
public CategoryLogs(){
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public long getCatId() {
return catId;
}
public void setCatId(long catId) {
this.catId = catId;
}
public String getCatName() {
return catName;
}
public void setCatName(String catName) {
this.catName = catName;
}
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
JOIN FETCH.
The FETCH keyword of the JOIN FETCH statement is JPA-specific. It tells the persistence provider to not only join the 2 database tables within the query but to also initialize the association on the returned entity. You can use it with a JOIN and a LEFT JOIN statement.
List<Parent> parents = em.createQuery("SELECT p FROM Parent p JOIN FETCH p.categoryLogs c
WHERE c.catId IN (:cat_Ids) " , Parent.class)
.setParameterList("cat_Ids",your_cat_id_list )
.getResultList();
I am getting a mappedBy reference an unknown target entity property in my code but I just done see where the problem is. Ive looked it over so many times i'm certain its starring me in the face but I just done see it.
My error is
mappedBy reference an unknown target entity property: com.jms.helloworld.domain.EventType.eventmasters in com.jms.helloworld.domain.EventMasters.eventType
package com.jms.helloworld.domain;
import static javax.persistence.GenerationType.IDENTITY;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
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;
#Entity
#Table(name = "EVENTTYPES")
#NamedQueries({
#NamedQuery(name="EventType.findAllWithDetail",
query="select distinct e from EventType e left join fetch e.events n ")
})
public class EventType implements Serializable {
private int id;
private String name;
private EventMasters eventmasters;
private Set<Events> events = new HashSet<Events>();
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(mappedBy = "eventtype", cascade=CascadeType.ALL, orphanRemoval=true)
public Set<Events> getEvents() {
return events;
}
public void setEvents(Set<Events> events) {
this.events = events;
}
#ManyToOne
#JoinColumn(name = "EVENTMASTER_ID")
public EventMasters getEventMasters() {
return eventmasters;
}
public void setEventMasters(EventMasters eventmasters) {
this.eventmasters = eventmasters;
}
}
and
package com.jms.helloworld.domain;
import static javax.persistence.GenerationType.IDENTITY;
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
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.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name="EVENTMASTERS")
/*
#NamedQueries({
#NamedQuery(name="Menus.findAllWithID",
query="select distinct c from Menus c left join fetch c.category t left join fetch t.items h" +
" where c.site_id = :id")
})
*/
public class EventMasters implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int id;
private String name;
private Sites sites;
private Set<EventType> eventtype = new HashSet<EventType>();
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToOne
#JoinColumn(name = "SITE_ID")
public Sites getSites() {
return sites;
}
public void setSites(Sites sites) {
this.sites = sites;
}
#OneToMany(mappedBy = "eventmasters", cascade=CascadeType.ALL, orphanRemoval=true)
public Set<EventType> getEventType() {
return eventtype;
}
public void setEventType(Set<EventType> eventtype) {
this.eventtype = eventtype;
}
Fix your property camel-case naming.
If your getter is getEventType() then mappedBy attribute should be eventType (similar problem is in eventmasters => eventMasters).
Here are my hibernate classes
package com.vaannila.domain;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.web.bind.annotation.ModelAttribute;
#Entity
#Table(name = "countries")
public class Country {
#Id
#Column(name = "country_id")
#GeneratedValue
private Integer country_id;
#Column(name = "country_name")
private String country_name;
public Country(Integer country_id , String name ){
this.country_name = name;
this.country_id = country_id;
}
/**
* #param country_id the country_id to set
*/
public void setCountry_id(Integer country_id) {
this.country_id = country_id;
}
/**
* #return the country_id
*/
public Integer getCountry_id() {
return country_id;
}
/**
* #param country_name the country_name to set
*/
public void setCountry_name(String country_name) {
this.country_name = country_name;
}
/**
* #return the country_name
*/
public String getCountry_name() {
return country_name;
}
}
Person java
package com.vaannila.domain;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.CascadeType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.validation.constraints.*;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
/**
* A simple POJO representing a Person
*/
#Entity
#Table(name = "PERSON")
public class Person implements Serializable {
private static final long serialVersionUID = -5527566248002296042L;
#Id
#Column(name = "ID")
#GeneratedValue
private Integer id;
#Column(name = "FIRST_NAME")
private String firstName;
#Column(name = "LAST_NAME")
private String lastName;
#Column(name = "MONEY")
private Double money;
#OneToMany(cascade = CascadeType.ALL)
#JoinTable(name = "person_countries", joinColumns = { #JoinColumn(name = "person_id") },
inverseJoinColumns = { #JoinColumn(name = "country_id") })
private List<Country> student_countries ;
public List<Country> getStudent_countries() {
return this.student_countries;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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 Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
}
jsp form
<tr><td>Country :</td>
<td><form:checkboxes path="student_countries" items="${countryList}" itemValue="country_id" itemLabel="country_name" /></td>
</tr>
</table>
DAO Logic
public void add(Person person) {
logger.debug("Adding new person");
// Retrieve session from Hibernate
Session session = sessionFactory.getCurrentSession();
// Save
session.save(person);
}
But my countries are not added in the database, all other things go in person table but not in relationship table.
Tested your code, works for me. Make sure your config settings are correct and not overridden.
I guess that the probem is that you do not have a 1:n Releationship, you have a n:m! Because your person have many studend contryies, and I guess that every country can have more than one person.
So replace the #OneToMany(cascade = CascadeType.ALL) in Person by an #ManyToMany relationship.