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.
Related
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);
All I need help i create this simple class where Category have list of Categories. When i try to save the list of sub categories with the Parent category it's show below error.
Json:-
{
"name": "n11111111",
"detail": "detail",
"status" : "AVAILABLE",
"subCategories": [3, 12, 100, 7, 11] // id of sub-cat
}
Class:-
#Entity
#Table(name = "category")
public class Category{
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
#Column(nullable = false, updatable = false, name = "category_id")
private Long id;
#Column(name = "name", nullable=false)
private String name;
#Column(name = "detail", nullable=false)
private String detail;
#Column(nullable = false, name = "status")
#Enumerated(EnumType.ORDINAL)
private Status status;
#OneToMany( targetEntity=Category.class, cascade=CascadeType.ALL)
private List<Category> subCategories;
}
ERROR:- "message": "could not execute statement; SQL [n/a]; constraint [UK_76grwe00i7mrj7awuvhc3kx0n]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
MYSQL ERROR:- #1062 - Duplicate entry
Code:- Convert from Vo to POJO
private Categorie getCatToPojo(CategorieVo categorieVo, String type) {
double startTime = System.nanoTime();
logger.info("Start Vo To Pojo Categorie");
// #:- case:-1 when no sub-cat there it save only below 3 attribute
this.categorie = new Categorie();
this.saveNameCat(categorieVo, type);
this.categorie.setDetail(categorieVo.getDetail());
this.categorie.setStatus(categorieVo.getStatus());
// #:- case:-2 when have list of sub-cat then will exe then next process
if((CollectionUtils.isNotEmpty(categorieVo.getSubCategories()) && categorieVo.getSubCategories().size() > 0) && type.equalsIgnoreCase("P")) {
logger.debug("Sub-Process....SubCategories...init");
// #:- S-Cat will be get and
List<Categorie> subCategories = this.businessServer.findAllById(categorieVo.getSubCategories())
.stream().filter(categorie1 -> categorie1.getName().startsWith("S-") == true ).collect(Collectors.toList());
// #:- if any wrong id pass it will not give you the list
if(CollectionUtils.isNotEmpty(subCategories) && subCategories.size() > 0) {
this.categorie.setSubCategories(subCategories);
}
logger.debug("Sub-Process....SubCategories...End " + categorieVo.getSubCategories().toString());
}
logger.debug(SecurityUtil.getPerfLog("Process Time For Convert the Vo to POJO", this.categorie.toString(), startTime));
logger.info("End Vo To Pojo Categorie");
return categorie;
}
private void saveNameCat(CategorieVo categorieVo, String type) {
switch (type) {
case "P":
// #:- P,S will join with name
this.categorie.setName(type + "-" + categorieVo.getName());
break;
case "S":
// #:- P,S will join with name
this.categorie.setName(type + "-" + categorieVo.getName());
break;
default:
logger.info("End Vo To Pojo Categorie With Exception");
// #:- will throw error bad request of type
throw new BadTypeException(" [ " + "Bad Request Type" + " ]--[ " + type + " ]");
}
}
Once I have to do exact same thing. Here is the working code for same purpose :
#Entity
#Data
#NoArgsConstructor
#Table(name = "categories")
public class Category {
#JsonProperty("Id")
#Id
private int id;
#JsonProperty("Code")
private String code;
#JsonProperty("Name")
private String name;
#JsonProperty("ParentId")
#Column(name = "parent_id")
private Integer parent;
#JsonProperty("NewAdminId")
private int newAdminId;
#JsonProperty("VolumetricWeight")
#Column(name = "volumetricWeight")
private Float volumetricWeight = 0.0f;
#JsonProperty("Nodes")
#OneToMany(
cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
orphanRemoval = true)
#JoinColumn(name = "parent_id")
private List<Category> categories;
public Category(int id, String code, String name, int newAdminId, List<Category> categories) {
this.id = id;
this.code = code;
this.name = name;
this.newAdminId = newAdminId;
this.categories = categories;
}
}
insert into `db`.`category` values (1, 'a');
insert into `db`.`category` values (2, 'b');
insert into `db`.`category` values (3, 'c');
commit;
insert into `db`.`subcategory` values (1, 2);
insert into `db`.`subcategory` values (1, 3);
import java.util.Set;
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.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
#Entity
#Table(name = "category")
public class Category {
#SuppressWarnings("unused")
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
private int id;
#Column(name="name")
private String name;
#ManyToMany(fetch=FetchType.EAGER)
#Cascade({CascadeType.ALL})
#JoinTable(name="subcategory",
joinColumns={#JoinColumn(name="idcategory")},
inverseJoinColumns={#JoinColumn(name="idsubcategory")})
private Set<Category> catlist;
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 Set<Category> getCatlist() {
return catlist;
}
public void setCatlist(Set<Category> catlist) {
this.catlist = catlist;
}
}
Here is another case of this ERROR:
21:22:15,881 ERROR [SessionFactoryImpl] Error in named query: ch.software.gvs.TroubleNotification_DeviceType.byType org.hibernate.QueryException:
could not resolve property: type of: ch.ildsoftware.gvs.TroubleNotification_DeviceType
[select d.id from ch.ildsoftware.gvs.TroubleNotification_DeviceType d where d.type = :type]
I have following setting:
queries.xml:
<named-query name="ch.ildsoftware.gvs.TroubleNotification_DeviceType.byType">
<query>
select t.id from TroubleNotification_DeviceType t where t.type = :type
</query>
</named-query>
TroubleNotification_DeviceType.java
import java.io.Serializable;
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;
#Entity
#Table(name = "tblgwTroubleNotification_ADSTyp")
public class TroubleNotification_DeviceType implements Serializable {
private static final long serialVersionUID = 1L;
private TroubleNotification id;
private DeviceType type;
private String createdBy;
private String createdDate;
public TroubleNotification_DeviceType()
{}
public TroubleNotification_DeviceType(TroubleNotification id, DeviceType type) {
this.id = id;
this.type = type;
}
#Id
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "IDgwTroubleNotification", nullable = false)
public TroubleNotification getId() {
return id;
}
public void setId(TroubleNotification id) {
this.id = id;
}
#Id
#Column(name = "ADSTypID", nullable = false)
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "GeraeteTypID", nullable = false)
public DeviceType getType() {
return type;
}
public void setType(DeviceType type) {
this.type = type;
}
#Column(name = "Created", nullable = false)
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
#Column(name = "CreatedDate", nullable = false)
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
}
I suspect there might be something wrong with the #Column and #JoinColumn annotation. It's just that the column-name I join with, is from a view which aliases the column name.
But maybe something else is wrong. I'm rather new to this.
snippet out of DeviceType:
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
....
#Id
#Column(name = "GeraeteTypID", nullable = false)
public Integer getId()
{
return this.id;
}
In other classes the reference would be like this, and work well (yet the column name is identical):
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "GeraeteTypID", nullable = false)
public DeviceType getType()
{
return this.type;
}
snippet out of an EJB:
#Override
#SuppressWarnings("unchecked")
public List<TroubleNotification> getTroubleNotificationByDeviceType(DeviceType aType)
{
// first get all IDgwTroubleNotification for ADSTypID
Query idSet = gvsData.createNamedQuery(
TroubleNotification_DeviceType.class.getName() + ".byType");
idSet.setParameter("type", aType);
List<TroubleNotification> idSetResult = idSet.getResultList();
final List<TroubleNotification> troubleNotificationResult = new ArrayList<TroubleNotification>();
for (int i = 0; i < idSetResult.size(); i++) {
// get all Notification for IDgwTroubleNotification
Query notificationById = gvsData.createNamedQuery(
TroubleNotification.class.getName() + ".byId");
notificationById.setParameter("id", idSetResult.get(i));
troubleNotificationResult.add((TroubleNotification) notificationById.getResultList());
}
return troubleNotificationResult;
}
Thank you for your help!
I discovered that my DB mapping was not at all proper. I have an n:m relation, which doesn't seem like an easy one with hibernate. But this was very helpful:
Hibernate Many-To-Many Revisited
But that was still not solving the problem. And I discovered that I have composite primary keys, that the primary keys of two tables are mapped in the n:m table. Another not so easy setting. So I followed this thread: Mapping ManyToMany with composite Primary key and Annotation:
The configuration from the second link, together with an SQL statement according to the second strategy in the first link works.
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.
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)