I am using an Employee and Company class as an example. In a Java persistence environment (Hibernate), when a bean is processing an Employee class with its' own Entity Manager, how can I call a Company class bean method when that object has its' own Entity Manager? DO I have to do a one to one mapping or can I call the method via the Application Config somehow?
Thanks.
You can use one to one mapping. I have implemented recently with product and team class. I have marked product as entity and team as entity. Below is the code which you would need to make it work. There are other ways to configure as well. In the below config you would require one table to store product, one table to store team and third team to store the productid and teamid.
***Product Class**
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.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.codehaus.jackson.annotate.JsonBackReference;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
#Entity
#Table(name="Product")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Product implements Serializable{
/**
*
*/
private static final long serialVersionUID = -5392649457041674962L;
#Id
#Column(name="productId")
#GeneratedValue
private Long productId;
#Column(name="productName")
private String productName;
#Column(name="productHasVariations")
private String productHasVariations;
#Column(name="productImgPath")
private String productImgPath;
#Column(name="productDesc")
private String productDesc;
// //---------------------------------------item mapped to league------------------------------------------//
#JsonBackReference
#OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
#JoinTable(
name="ProductLeague",
joinColumns= #JoinColumn(name="productId"),
inverseJoinColumns = #JoinColumn(name="leagueId")
)
private League league;
// //--------------------------------------------------------------------------------------------------------//
//
// //---------------------------------------item mapped to category------------------------------------------//
#JsonBackReference
#OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinTable(
name="ProductCategory",
joinColumns= #JoinColumn(name="productId"),
inverseJoinColumns = #JoinColumn(name="categoryId")
)
private Category category;
// //--------------------------------------------------------------------------------------------------------//
//
// //---------------------------------------item mapped to team------------------------------------------//
#JsonBackReference
#OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinTable(
name="ProductTeam",
joinColumns= #JoinColumn(name="productId"),
inverseJoinColumns = #JoinColumn(name="teamId")
)
private Team team;
// //--------------------------------------------------------------------------------------------------------//
//
// //---------------------------------------item mapped to flags such as featured, sale, hot, new------------//
#JsonBackReference
#OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
#JoinTable(
name="ProductFlag",
joinColumns= #JoinColumn(name="productId"),
inverseJoinColumns = #JoinColumn(name="flagId")
)
private Flag flag;
//--------------------------------------------------------------------------------------------------------//
//
//---------------------------------------item mapped to sizes ------------//
#JsonBackReference
#OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
#OrderBy("sizeId asc")
#JoinTable(
name="ProductSize",
joinColumns= #JoinColumn(name="productId"),
inverseJoinColumns = #JoinColumn(name="sizeId")
)
private Set<Size> size;
// //--------------------------------------------------------------------------------------------------------//
//---------------------------------------item mapped to prices ------------//
#JsonBackReference
#OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
#OrderBy("priceId asc")
#JoinTable(
name="ProductPrice",
joinColumns = { #JoinColumn(name="productId")
},
inverseJoinColumns = #JoinColumn(name="priceId")
)
private Set<Price> price;
// //--------------------------------------------------------------------------------------------------------//
// //--------------------------------------------------------------------------------------------------------//
//---------------------------------------item mapped to discounts ------------//
#JsonBackReference
#OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
#JoinTable(
name="ProductDiscount",
joinColumns = { #JoinColumn(name="productId")
},
inverseJoinColumns = #JoinColumn(name="discountId")
)
private Discount discount;
// //--------------------------------------------------------------------------------------------------------//
#Transient
private Long productQuantity;
#Transient
private String productPriceBeforeDiscount;
#Transient
private String productPriceAfterDiscount;
#Transient
private String productSelectedSize;
public Flag getFlag() {
return flag;
}
public void setFlag(Flag flag) {
this.flag = flag;
}
public Long getProductId() {
return this.productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
public String getProductName() {
return this.productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public void setProductHasVariations(String productHasVariations) {
this.productHasVariations = productHasVariations;
}
public String getProductHasVariations() {
return productHasVariations;
}
public void setLeague(League league) {
this.league = league;
}
public League getLeague() {
return league;
}
public Category getCategory() {
return this.category;
}
public void setCategory(Category category) {
this.category = category;
}
public Team getTeam() {
return this.team;
}
public void setTeam(Team team) {
this.team = team;
}
public String getProductImgPath() {
return productImgPath;
}
public void setProductImgPath(String productImgPath) {
this.productImgPath = productImgPath;
}
public void setProductDesc(String productDesc) {
this.productDesc = productDesc;
}
public String getProductDesc() {
return productDesc;
}
public void setSize(Set<Size> size) {
this.size = size;
}
public Set<Size> getSize() {
return size;
}
public void setPrice(Set<Price> price) {
this.price = price;
}
public Set<Price> getPrice() {
return price;
}
public void setProductQuantity(Long productQuantity) {
this.productQuantity = productQuantity;
}
public Long getProductQuantity() {
return productQuantity;
}
public void setDiscount(Discount discount) {
this.discount = discount;
}
public Discount getDiscount() {
return discount;
}
public void setProductPriceAfterDiscount(String productPriceAfterDiscount) {
this.productPriceAfterDiscount = productPriceAfterDiscount;
}
public String getProductPriceAfterDiscount() {
return productPriceAfterDiscount;
}
public void setProductPriceBeforeDiscount(String productPriceBeforeDiscount) {
this.productPriceBeforeDiscount = productPriceBeforeDiscount;
}
public String getProductPriceBeforeDiscount() {
return productPriceBeforeDiscount;
}
public void setProductSelectedSize(String productSelectedSize) {
this.productSelectedSize = productSelectedSize;
}
public String getProductSelectedSize() {
return productSelectedSize;
}
}
****TeamClass********
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.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.io.Serializable;
#Entity
#Table(name="Team")
public class Team implements Serializable{
/**
*
*/
private static final long serialVersionUID = 5969057417203282157L;
#Id
#Column(name="teamId")
#GeneratedValue
private Integer teamId;
#Column(name="teamName")
private String teamName;
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
#JoinTable(
name="ProductTeam",
joinColumns = #JoinColumn(name="teamId"),
inverseJoinColumns = #JoinColumn(name="productId")
)
public Set<Product> product;
public Integer getTeamId() {
return this.teamId;
}
public void setTeamId(Integer teamId) {
this.teamId = teamId;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public Set<Product> getProduct() {
return product;
}
public void setProduct(Set<Product> product) {
this.product = product;
}
}
Related
Two days of thinking and searching and any result - internet and documentation do not answer my question.
I need to construct a Jpa Repository method name to get a Set<Recipe> from database, by field of Ingredient ,ingrName. I am also using a join table and entity RecipeIngredient to store the amount of each ingredient in the Recipe using RecipeIngredient
Help, please.
Thanks!
I try to make something like this:
package com.pck.repository;
import com.pck.Recipe;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Set;
#Repository
public interface RecipeRepository extends JpaRepository<Recipe, Integer> {
public Set<Recipe> findAllByRecipeIngrs_Ingredient_IngrNameIn(Collection<String> ingredientNames)
}
But it does'nt works.
Recipe:
package com.pck.entity;
import javax.persistence.*;
import java.util.*;
#Entity
#Table(name="recipes")
public class Recipe {
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "recipe")
private Set<RecipeIngredient> recipeIngrs;
public Recipe() {}
public Set<RecipeIngredient> getRecipeIngrs() {
return ingredients;
}
public void setRecipeIngrs(Set<RecipeIngredient> recipeIngrs) {
this.recipeIngrs = recipeIngrs;
}
// ... other fields, constructors, getters, setters
}
RecipeIngredient:
package com.pck.entity;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Table(name="recipe_ingredient")
public class RecipeIngredient {
#JsonIgnore
#ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
#JoinColumn(name = "recipe_id")
private Recipe recipe;
#ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
#JoinColumn(name = "ingredient_id")
private Ingredient ingredient;
#Column(name = "ingredient_amount_grams")
private double ingredientAmountGrams;
public RecipeIngredient() {}
public Recipe getRecipe() {
return recipe;
}
public void setRecipe(Recipe recipe) {
this.recipe = recipe;
}
public Ingredient getIngredient() {
return ingredient;
}
public void setIngredient(Ingredient ingredient) {
this.ingredient = ingredient;
}
public double getIngredientAmountGrams() {
return ingredientAmountGrams;
}
public void setIngredientAmountGrams(double ingredientAmountGrams) {
this.ingredientAmountGrams = ingredientAmountGrams;
}
// ... other fields, constructors, getters, setters
}
Ingredient:
package com.pck.entity;
import javax.persistence.*;
import java.util.*;
#Entity
#Table(name="ingredient")
public class Ingredient{
#Column(name="ingr_name")
private String ingrName;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "ingredient")
private Set<RecipeIngredient> recipeIngrs;
public Ingredient() {}
public String getIngrName() {
return ingrName;
}
public void setIngrName(String ingrName) {
this.ingrName = ingrName;
}
public Set<RecipeIngredient> getRecipeIngrs() {
return recipeIngrs;
}
public void setRecipeIngrs(Set<RecipeIngredient> recipeIngrs) {
this.recipeIngrs = recipeIngrs;
}
}
You can leverage jpql:
#Query("select r from Recipe r inner join r.recipeIngrs ri inner join ri.ingredient i where i.ingrName in :names")
public Set<Recipe> findAllByIngrNameIn(#Param("names") Collection<String> ingredientNames)
I am using Hibernate to fetch the JSON object from DB. I want that JSON object should contain all the details of the only top two of most recently created VGIs. But I don't know how to limit the result set and then sort on the basis of created date when no HQL query is used. It is fetching all the details from MySQL db.
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name = "vgi", catalog = "coworkee5")
public class VGI {
#ManyToOne
#JoinColumn(name = "employee_id", referencedColumnName = "id", insertable = false, updatable = false)
private Employees employees;
public Employees getEmployees() {
return employees;
}
public void setEmployees(Employees employees) {
this.employees = employees;
}
#OneToMany(cascade = CascadeType.ALL, targetEntity = VgiGoals.class, mappedBy = "vgi")
private List<VgiGoals> vgiGoals;
public List<VgiGoals> getVgiGoals() {
return vgiGoals;
}
public void setVgi_goals(List<VgiGoals> vgiGoals) {
this.vgiGoals = vgiGoals;
}
public VGI() {
}
#Id
#Column(name = "id")
private String id;
#Column(name = "title")
private String vgi;
#Column(name = "employee_id")
private String employee_id;
#Column(name = "created_on")
private String created;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getvgi() {
return vgi;
}
public void setvgi(String vgi) {
this.vgi = vgi;
}
public String getEmployee_id() {
return employee_id;
}
public void setEmployee_id(String employee_id) {
this.employee_id = employee_id;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
}
Add #OrderBy annotation to sort like below.
#OneToMany(cascade = CascadeType.ALL, targetEntity = VgiGoals.class, mappedBy = "vgi")
#OrderBy("createdOn DESC")
private List<VgiGoals> vgiGoals;
NOTE : replace createdOn with your date field in VgiGoals class.
And for limit use below method in the query.
query.setFirstResult(1).setMaxResults(10);
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 have to put two tomcat servers (tcat01 and tcat02) in a loadbalancing architecture.
I'm using tomcat 6.x and I edited the conf/server.xml like this on tomcat tcat01 :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tcat01">
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="6"/>
....
On tcat02 conf/server.xml is like this :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tcat02">
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="6"/>
....
I started tcat01, and then tcat02, il catalina.out it seems that tcat01 communicates well with tcat02.
Then I connected to the webapp with internet navigator, and then each time I do something in the webapp (I mean when I navigate) there is this exception :
Nov 24, 2011 12:00:13 AM org.apache.catalina.core.ContainerBase backgroundProcess
WARNING: Exception processing manager org.apache.catalina.ha.session.DeltaManager#278c4835 background process
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.mycompany.myproject.model.authentification.Authority.groups, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentSet.toString(PersistentSet.java:332)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
And here is the code of the class which cannot be sezialized (ie the java bean mentioned in the stack trace) :
import static javax.persistence.GenerationType.IDENTITY;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
#Entity
#Table(name = "authority", uniqueConstraints = #UniqueConstraint(columnNames = "name"))
public class Authority implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -7436593455923433675L;
//SYSTEM ROLE CONSTANT
public static final String MANAGER_SYSTEM_ROLE = "ROLE_MANAGER";
public static final String CLIENT_SYSTEM_ROLE = "ROLE_CLIENT";
public static final String PEDAGO_ADMIN_SYSTEM_ROLE = "ROLE_PEDAGO_ADMIN";
private Integer id;
#Size(min=1)
#Pattern(regexp="^ROLE[_a-zA-Z]+$", message="{authority.name.pattern.error}")
private String name;
#Size(max=65535)
private String description;
private Boolean isSystem;
private Set<Group> groups = new HashSet<Group>(0);
public Authority() {
this.isSystem = false;
}
public Authority(String name) {
this.name = name;
this.isSystem = false;
}
public Authority(String name, String description, Set<Group> groups) {
this.name = name;
this.description = description;
this.groups = groups;
this.isSystem = false;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "name", unique = true, nullable = false, length = 45)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "description")
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public void setIsSystem(Boolean isSystem) {
this.isSystem = isSystem;
}
#Column(name = "system")
public Boolean getIsSystem() {
return isSystem;
}
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "group_authorities", joinColumns = { #JoinColumn(name = "authority_id", nullable = false, updatable = true) }, inverseJoinColumns = { #JoinColumn(name = "group_id", nullable = false, updatable = true) })
public Set<Group> getGroups() {
return this.groups;
}
public void setGroups(Set<Group> groups) {
this.groups = groups;
}
#PrePersist
protected void updateSystemField() {
if(isSystem == null)
isSystem = false;
}
}
And here is the code of the java bean Group (cause we have a lazily initialize exception on a collection of Groups) :
import static javax.persistence.GenerationType.IDENTITY;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
#Entity
#Table(name = "groups", uniqueConstraints = #UniqueConstraint(columnNames = "name"))
public class Group implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 7380068327050752558L;
private Integer id;
#NotNull
#Size(min=1)
private String name;
private String description;
private Boolean isSystem;
private Set<Authority> authorities = new HashSet<Authority>(0);
private Set<User> users = new HashSet<User>(0);
public Group() {
this.isSystem = false;
}
public Group(String name) {
this.name = name;
this.isSystem = false;
}
public Group(String name, String description, Set<Authority> authorities, Set<User> users) {
this.name = name;
this.description = description;
this.isSystem = false;
this.authorities = authorities;
this.users = users;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "name", unique = true, nullable = false, length = 45)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "description")
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public void setIsSystem(Boolean isSystem) {
this.isSystem = isSystem;
}
#Column(name = "system")
public Boolean getIsSystem() {
return isSystem;
}
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "group_authorities", joinColumns = { #JoinColumn(name = "group_id", nullable = false, updatable = true) }, inverseJoinColumns = { #JoinColumn(name = "authority_id", nullable = false, updatable = true) })
public Set<Authority> getAuthorities() {
return this.authorities;
}
public void setAuthorities(Set<Authority> authorities) {
this.authorities = authorities;
}
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "group_users", joinColumns = { #JoinColumn(name = "group_id", nullable = false, updatable = true) }, inverseJoinColumns = { #JoinColumn(name = "user_id", nullable = false, updatable = true) })
public Set<User> getUsers() {
return this.users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public void addAuthority(Authority authority) {
if(authorities == null)
authorities = new HashSet<Authority>(0);
authorities.add(authority);
}
public boolean removeAuthority(Authority authority) {
return authorities == null || authorities.remove(authority);
}
public void addUser(User user) {
if(users == null)
users = new HashSet<User>(0);
users.add(user);
}
public boolean removeUser(User user) {
return users == null || users.remove(user);
}
#PrePersist
protected void updateSystemField() {
if(isSystem == null)
isSystem = false;
}
}
Thanks for your help
You're getting the lazy instantiation exception since you have authority groups mapped as lazy. By the time the session is replicated, you're outside of an active session so it can't be hydrated. To remedy this, you have a few options:
Change your mapping so the association is fetched eagerly
Change your DAO to step into that collection (or use hibernate.initialize) to force the lazy load to occur before the session is closed
Detach the object from the session and then explicitly set the groups to null on the object before it is put into session to replace the hibernate proxy that is there.
For this particuar case, options 1 or 2 are probably the cleanest.
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.