Tomcat loadbalancing serialize exception PersistenceExceptionTranslationInterceptor : lazy initialization exception - java

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.

Related

How can we sort the result by date in Hibernate?

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);

Map external id to local id

In my app users can add movies to their watchlist. The movie data comes from an external API. Each movie has its own unique id. For example: Star Wars - A new hope has id 11. And Fight Club has id 550.
When a user adds a movie I pass the whole movie object from the front-end to the back-end:
Component:
createMovie(movie: Movie): void {
this._dataService.createMovie<Movie>({'name': 'Star Wars - A new hope', 'id': 11})
.subscribe((data) => this.movies.push(data),
error => () => {
'something went wrong';
},
() => {
// console.log(this.movies);
});
}
In this case I'm using example data.
Service:
public createMovie<T>(movie: Movie): Observable<T> {
return this.http.post<T>('/api/movies/', movie, {headers: this.getToken()});
}
The MovieController in the back-end:
#RequestMapping(value = "/", method = RequestMethod.POST)
public Movie createMovie(#RequestBody Movie movie){
return movieService.createMovie(movie);
}
The MovieService:
#Override
public Movie createMovie(Movie movie) {
User current_user = userService.getUser();
current_user.addMovie(movie);
userRepository.save(current_user);
return movie;
}
And the User model:
public void addMovie(Movie movie) {
movies.add(movie);
movie.getUsers().add(this);
}
When the movie is saved in the database it's saved with a unique id, starting from 1. How would I map the id from the front-end to the id of the object in my database? I could create another column "external_id" and map it to that, but I think that's a lesser solution than to use the id from the external API.
//edit. Added my movie and user model:
package com.movieseat.models;
import com.movieseat.model.security.User;
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;
#Entity(name = "Movie")
#Table(name = "movie")
public class Movie {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Integer id;
private String name;
private String description;
#ManyToMany(mappedBy = "movies")
private Set<User> users = new HashSet<>();
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
User model:
package com.movieseat.model.security;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.movieseat.models.Movie;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
#Entity(name = "User")
#Table(name = "USER")
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class User {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
#SequenceGenerator(name = "user_seq", sequenceName = "user_seq", allocationSize = 1)
private Long id;
#Column(name = "USERNAME", length = 50, unique = true)
#NotNull
#Size(min = 4, max = 50)
private String username;
#Column(name = "PASSWORD", length = 100)
#NotNull
#Size(min = 4, max = 100)
private String password;
#Column(name = "FIRSTNAME", length = 50)
#NotNull
#Size(min = 4, max = 50)
private String firstname;
#Column(name = "LASTNAME", length = 50)
#NotNull
#Size(min = 4, max = 50)
private String lastname;
#Column(name = "EMAIL", length = 50)
#NotNull
#Size(min = 4, max = 50)
private String email;
#Column(name = "ENABLED")
#NotNull
private Boolean enabled;
#Column(name = "LASTPASSWORDRESETDATE")
#Temporal(TemporalType.TIMESTAMP)
#NotNull
private Date lastPasswordResetDate;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(
name = "USER_AUTHORITY",
joinColumns = {#JoinColumn(name = "USER_ID", referencedColumnName = "ID")},
inverseJoinColumns = {#JoinColumn(name = "AUTHORITY_ID", referencedColumnName = "ID")})
private List<Authority> authorities;
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 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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public List<Authority> getAuthorities() {
return authorities;
}
public void setAuthorities(List<Authority> authorities) {
this.authorities = authorities;
}
public Date getLastPasswordResetDate() {
return lastPasswordResetDate;
}
public void setLastPasswordResetDate(Date lastPasswordResetDate) {
this.lastPasswordResetDate = lastPasswordResetDate;
}
#ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinTable(name = "user_movie",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "movie_id", referencedColumnName = "id")
)
private Set<Movie> movies = new HashSet<>();
public void addMovie(Movie movie) {
movies.add(movie);
movie.getUsers().add(this);
}
public void removeMovie(Movie movie) {
movies.remove(movie);
movie.getUsers().remove(this);
}
}

java persistence cross object method access

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;
}
}

#ManyToOne with JOIN FetchMode generating inner join

Reading all the documentation, using #Fetch(FetchMode.JOIN) on a #ManyToOne should by default I believe generate a left outer join, but for me it is always generating an inner join. These are my beans:
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.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
/**
* PensionMember entity. #author MyEclipse Persistence Tools
*/
#Entity
#Table(name = "Z_PENSION_MEMBERS", schema = "DANAOS")
public class PensionMember implements java.io.Serializable {
private static final long serialVersionUID = -4541446336298304689L;
// Fields
private Long id;
private Long personsCode;
private String employeeCode;
private String personType;
private CrewOfficeEmployee employee;
private PersonTO person;
// Property accessors
#Id
#Column(name = "ID", unique = true, nullable = false, precision = 0)
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "EMPLOYEE_CODE", length = 12)
public String getEmployeeCode() {
return this.employeeCode;
}
public void setEmployeeCode(String employeeCode) {
this.employeeCode = employeeCode;
}
#ManyToOne( cascade = CascadeType.REFRESH, optional=true )
#JoinColumn( name = "EMPLOYEE_CODE", insertable = false, updatable = false )
#Fetch(FetchMode.JOIN)
public CrewOfficeEmployee getEmployee(){
return employee;
}
public void setEmployee( CrewOfficeEmployee employee ){
this.employee = employee;
}
#Column(name = "PERSONS_CODE", precision = 126, scale = 0, insertable = false, updatable = false)
public Long getPersonsCode() {
return this.personsCode;
}
public void setPersonsCode(Long personsCode) {
this.personsCode = personsCode;
}
#ManyToOne( cascade = CascadeType.REFRESH, optional=true )
#JoinColumn( name = "PERSONS_CODE" )
#Fetch(FetchMode.JOIN)
public PersonTO getPerson() {
return person;
}
public void setPerson(PersonTO person) {
this.person = person;
}
#Column(name = "PERSON_TYPE", nullable = false, length = 1)
public String getPersonType() {
return this.personType;
}
public void setPersonType(String personType) {
this.personType = personType;
}
}
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
/**
* CrewOfficeEmployee entity. #author MyEclipse Persistence Tools
*/
#Entity
#Table(name = "Z_CREW_OFFICE_EMPLOYEES", schema = "DANAOS")
public class CrewOfficeEmployee implements java.io.Serializable {
private static final long serialVersionUID = -5900130959401376537L;
// Fields
private String id;
private Integer crewOfficeJobTitleId;
private String name;
private String surname;
private Date dateOfBirth;
private Date effectiveJoiningDate;
private Date joiningDate;
private Date leavingDate;
// Property accessors
#Id
#Column(name = "ID", unique = true, nullable = false, length = 12)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#Column(name = "JOB_TITLE_ID", nullable = false)
public Integer getCrewOfficeJobTitleId() {
return crewOfficeJobTitleId;
}
public void setCrewOfficeJobTitleId(Integer crewOfficeJobTitleId) {
this.crewOfficeJobTitleId = crewOfficeJobTitleId;
}
#Column(name = "NAME", nullable = false, length = 30)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "SURNAME", nullable = false, length = 30)
public String getSurname() {
return this.surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
#Column(name = "DATE_OF_BIRTH", nullable = false, length = 7)
public Date getDateOfBirth() {
return this.dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
#Column(name = "EFFECTIVE_JOINING_DATE", nullable = false, length = 7)
public Date getEffectiveJoiningDate() {
return this.effectiveJoiningDate;
}
public void setEffectiveJoiningDate(Date effectiveJoiningDate) {
this.effectiveJoiningDate = effectiveJoiningDate;
}
#Column(name = "JOINING_DATE", nullable = false, length = 7)
public Date getJoiningDate() {
return this.joiningDate;
}
public void setJoiningDate(Date joiningDate) {
this.joiningDate = joiningDate;
}
#Column(name = "LEAVING_DATE", length = 7)
public Date getLeavingDate() {
return this.leavingDate;
}
public void setLeavingDate(Date leavingDate) {
this.leavingDate = leavingDate;
}
}
This is my query:
Criteria crit = getSession().createCriteria(PensionMember.class);
crit.createAlias("employee", "employee");
crit.createAlias("person", "person");
crit.add(
Restrictions.or(
Restrictions.and(
Restrictions.eq( PERSON_TYPE, "V" ),
Restrictions.like( "person.personsSurname", surname, MatchMode.START ).ignoreCase()
),
Restrictions.and(
Restrictions.eq( PERSON_TYPE, "O" ),
Restrictions.like( "employee.surname", surname, MatchMode.START ).ignoreCase()
)
)
);
... and this is the resulting SQL:
select * from ( select this_.ID as ID23020_6_, this_.EMPLOYEE_CODE as EMPLOYEE3_23020_6_, this_.PERSONS_CODE as PERSONS7_23020_6_,
this_.PERSON_TYPE as PERSON6_23020_6_, employee1_.ID as ID23010_0_, employee1_.JOB_TITLE_ID as JOB2_23010_0_,
employee1_.DATE_OF_BIRTH as DATE3_23010_0_, employee1_.EFFECTIVE_JOINING_DATE as EFFECTIVE4_23010_0_,
employee1_.JOINING_DATE as JOINING5_23010_0_, employee1_.LEAVING_DATE as LEAVING6_23010_0_,
employee1_.NAME as NAME23010_0_, employee1_.SURNAME as SURNAME23010_0_, person2_.STATUS_CODE as STATUS2_22758_1_, etc
from DANAOS.Z_PENSION_MEMBERS this_
inner join DANAOS.Z_CREW_OFFICE_EMPLOYEES employee1_ on this_.EMPLOYEE_CODE=employee1_.ID
inner join PERSONS person2_ on this_.PERSONS_CODE=person2_.PERSONS_CODE
where ((this_.PERSON_TYPE=? and lower(person2_.PERSONS_SURNAME) like ?) or
(this_.PERSON_TYPE=? and lower(employee1_.SURNAME) like ?)) ) where rownum <= ?
How come?! Can someone tell me what I'm doing wrong?
Thanks,
Neil
I'm using Hibernate 3.6.10 btw
Having realised it was the criteria query that was the problem, the solution was to change the createAlias() methods:
Criteria crit = getSession().createCriteria(PensionMember.class);
crit.createAlias("employee", "employee", CriteriaSpecification.LEFT_JOIN);
crit.createAlias("person", "person", CriteriaSpecification.LEFT_JOIN);
#ManyToOne( cascade = CascadeType.REFRESH, optional=true )
#JoinColumn( name = "EMPLOYEE_CODE", insertable = false, updatable = false )
#Fetch(FetchMode.JOIN)
public CrewOfficeEmployee getEmployee(){
return employee;
}
first of all change "insertable = false" to true.
I am getting(left outer join) :
Hibernate:
select this_.ID as ID1_1_1_, this_.EMPLOYEE_CODE1 as EMPLOYEE3_1_1_,
this_.EMPLOYEE_CODE as EMPLOYEE2_1_1_, crewoffice2_.ID as ID1_0_0_,
crewoffice2_.JOB_TITLE_ID as JOB_TITL2_0_0_,
crewoffice2_.DATE_OF_BIRTH as DATE_OF_3_0_0_,
crewoffice2_.EFFECTIVE_JOINING_DATE as EFFECTIV4_0_0_,
crewoffice2_.JOINING_DATE as JOINING_5_0_0_, crewoffice2_.LEAVING_DATE
as LEAVING_6_0_0_, crewoffice2_.NAME as NAME7_0_0_,
crewoffice2_.SURNAME as SURNAME8_0_0_ from Z_PENSION_MEMBERS this_
left outer join Z_CREW_OFFICE_EMPLOYEES crewoffice2_ on
this_.EMPLOYEE_CODE1=crewoffice2_.ID order by this_.ID asc
I think your code should work.

Hibernate : Use of #OneToMany or #ManyToMany targeting an unmapped class

i can't find where is my error, where i'm not mapping my class, but to me everything shoud be fine.. but isn't.
Can someone help me to find it ?
org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class: com.bytecode.entities.Event.categorytagit[com.bytecode.entities.Categorytagit]
at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1068)
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:600)
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:541)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:43)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1130)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:324)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1286)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)
package com.bytecode.entities;
// Generated 29/03/2011 12:15:48 by Hibernate Tools 3.2.1.GA
import java.util.Date;
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 static javax.persistence.GenerationType.IDENTITY;
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.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* Event generated by hbm2java
*/
#Entity
#Table(name = "event", catalog = "tagit")
public class Event implements java.io.Serializable {
private Integer id;
private User user;
private String name;
private Date iniEventDate;
private Date iniInscDate;
private Date endInscDate;
private String urlPicture;
private Integer idEventoFacebook;
private String description;
private Integer places;
private Integer lottery;
private String street;
private String city;
private Integer idMainEvent;
private Set<Tag> tags = new HashSet<Tag>(0);
private Set<Presentparticipants> presentparticipantses = new HashSet<Presentparticipants>(0);
private Set<User> users = new HashSet<User>(0);
private Set<Categorytagit> categorytagit = new HashSet<Categorytagit>(0);
public Event() {
}
public Event(User user, String name, Date iniEventDate, String description, String street, String city) {
this.user = user;
this.name = name;
this.iniEventDate = iniEventDate;
this.description = description;
this.street = street;
this.city = city;
}
public Event(User user, String name, Date iniEventDate, Date iniInscDate, Date endInscDate, String urlPicture, Integer idEventoFacebook, String description, Integer places, Integer lottery, String street, String city, Integer idMainEvent, Set<Tag> tags, Set<Presentparticipants> presentparticipantses, Set<User> users, Set<Categorytagit> categorytagit) {
this.user = user;
this.name = name;
this.iniEventDate = iniEventDate;
this.iniInscDate = iniInscDate;
this.endInscDate = endInscDate;
this.urlPicture = urlPicture;
this.idEventoFacebook = idEventoFacebook;
this.description = description;
this.places = places;
this.lottery = lottery;
this.street = street;
this.city = city;
this.idMainEvent = idMainEvent;
this.tags = tags;
this.presentparticipantses = presentparticipantses;
this.users = users;
this.categorytagit = categorytagit;
}
#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;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "idOrganizer", nullable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
#Column(name = "name", nullable = false, length = 55)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "iniEventDate", nullable = false, length = 19)
public Date getIniEventDate() {
return this.iniEventDate;
}
public void setIniEventDate(Date iniEventDate) {
this.iniEventDate = iniEventDate;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "iniInscDate", length = 19)
public Date getIniInscDate() {
return this.iniInscDate;
}
public void setIniInscDate(Date iniInscDate) {
this.iniInscDate = iniInscDate;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "endInscDate", length = 19)
public Date getEndInscDate() {
return this.endInscDate;
}
public void setEndInscDate(Date endInscDate) {
this.endInscDate = endInscDate;
}
#Column(name = "urlPicture")
public String getUrlPicture() {
return this.urlPicture;
}
public void setUrlPicture(String urlPicture) {
this.urlPicture = urlPicture;
}
#Column(name = "idEventoFacebook")
public Integer getIdEventoFacebook() {
return this.idEventoFacebook;
}
public void setIdEventoFacebook(Integer idEventoFacebook) {
this.idEventoFacebook = idEventoFacebook;
}
#Column(name = "description", nullable = false, length = 65535)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "places")
public Integer getPlaces() {
return this.places;
}
public void setPlaces(Integer places) {
this.places = places;
}
#Column(name = "lottery")
public Integer getLottery() {
return this.lottery;
}
public void setLottery(Integer lottery) {
this.lottery = lottery;
}
#Column(name = "street", nullable = false)
public String getStreet() {
return this.street;
}
public void setStreet(String street) {
this.street = street;
}
#Column(name = "city", nullable = false, length = 55)
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
#Column(name = "idMainEvent")
public Integer getIdMainEvent() {
return this.idMainEvent;
}
public void setIdMainEvent(Integer idMainEvent) {
this.idMainEvent = idMainEvent;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "event")
public Set<Tag> getTags() {
return this.tags;
}
public void setTags(Set<Tag> tags) {
this.tags = tags;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "event")
public Set<Presentparticipants> getPresentparticipantses() {
return this.presentparticipantses;
}
public void setPresentparticipantses(Set<Presentparticipants> presentparticipantses) {
this.presentparticipantses = presentparticipantses;
}
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinTable(name = "eventuser", catalog = "tagit", joinColumns = {
#JoinColumn(name = "idEvent", nullable = false, updatable = false)}, inverseJoinColumns = {
#JoinColumn(name = "idUser", nullable = false, updatable = false)})
public Set<User> getUsers() {
return this.users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinTable(name = "eventcategory", catalog = "tagit", joinColumns = {
#JoinColumn(name = "idEvent", nullable = false, updatable = false)}, inverseJoinColumns = {
#JoinColumn(name = "idCategory", nullable = false, updatable = false)})
public Set<Categorytagit> getCategorytagit() {
return this.categorytagit;
}
public void setCategorytagit(Set<Categorytagit> categorytagit) {
this.categorytagit = categorytagit;
}
}
My hibernate.cfg:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:xxxx</property>
<property name="hibernate.connection.username">xxxxxxxxx</property>
<property name="hibernate.connection.password">xxxxxxxxxxxx</property>
<property name="hibernate.current_session_context_class">thread</property>
<!-- Connection pool C3P0 -->
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">100</property>
<property name="hibernate.c3p0.timeout">20</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">60</property>
<!-- To show sql output on the screen -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<!-- Mapping the entities -->
<mapping class="com.bytecode.entities.Categorytagit"/>
<mapping class="com.bytecode.entities.Likes"/>
<mapping class="com.bytecode.entities.Categoryfacebook"/>
<mapping class="com.bytecode.entities.Accountconfirmation"/>
<mapping class="com.bytecode.entities.User"/>
<mapping class="com.bytecode.entities.Tag"/>
<mapping class="com.bytecode.entities.PresentparticipantsId"/>
<mapping class="com.bytecode.entities.Company"/>
<mapping class="com.bytecode.entities.Event"/>
<mapping class="com.bytecode.entities.Presentparticipants"/>
</session-factory>
</hibernate-configuration>
UPDATE:
package com.bytecode.entities;
// Generated 29/03/2011 12:15:48 by Hibernate Tools 3.2.1.GA
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 static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* Categorytagit generated by hbm2java
*/
#Entity
#Table(name = "categorytagit", catalog = "tagit")
public class Categorytagit implements java.io.Serializable {
private Integer id;
private String name;
private Set<Likes> likeses = new HashSet<Likes>(0);
private Set<Categoryfacebook> categoryfacebooks = new HashSet<Categoryfacebook>(0);
private Set<Event> events = new HashSet<Event>(0);
public Categorytagit() {
}
public Categorytagit(String name) {
this.name = name;
}
public Categorytagit(String name, Set<Likes> likeses, Set<Categoryfacebook> categoryfacebooks, Set<Event> events) {
this.name = name;
this.likeses = likeses;
this.categoryfacebooks = categoryfacebooks;
this.events = events;
}
#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", nullable = false, length = 55)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "categorytagit")
public Set<Likes> getLikeses() {
return this.likeses;
}
public void setLikeses(Set<Likes> likeses) {
this.likeses = likeses;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "categorytagit")
public Set<Categoryfacebook> getCategoryfacebooks() {
return this.categoryfacebooks;
}
public void setCategoryfacebooks(Set<Categoryfacebook> categoryfacebooks) {
this.categoryfacebooks = categoryfacebooks;
}
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinTable(name = "eventcategory", catalog = "tagit", joinColumns = {
#JoinColumn(name = "idCategory", nullable = false, updatable = false)}, inverseJoinColumns = {
#JoinColumn(name = "idEvent", nullable = false, updatable = false)})
public Set<Event> getEvents() {
return this.events;
}
public void setEvents(Set<Event> events) {
this.events = events;
}
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "idOrganizer", nullable = false)
public User getUser() {
return this.user;
}
I think you are missing target entity class to match your column.
#ManyToOne(targetEntity = User.class)

Categories