I'm trying to implement to following : Many to Many Hibernate Mapping for additional property in the join table
for creating many to many connection with extra fields. I keep getting this exception:
org.hibernate.MappingException: Repeated column in mapping for entity:
UserRole column: id (should be mapped with insert="false" update="false")
Why?
I'm using spring 4 and MySQL
My code:
#Entity
#AssociationOverrides({ #AssociationOverride(name = "pk.user", joinColumns = #JoinColumn(name = "id")),
#AssociationOverride(name = "pk.role", joinColumns = #JoinColumn(name = "id")) })
public class UserRole extends AbstractEntity {
private UserRoleId pk;
public UserRole(User user, Role role) {
super();
this.pk = new UserRoleId(user, role);
}
#EmbeddedId
public UserRoleId getPk() {
return pk;
}
public Long getUserId() {
return pk.getUser().getId();
}
public Long getRoleId() {
return pk.getRole().getId();
}
}
#Embeddable
public class UserRoleId implements Serializable {
private User user;
private Role role;
public UserRoleId(User user, Role role) {
super();
this.user = user;
this.role = role;
}
#ManyToOne
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#ManyToOne
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
#MappedSuperclass
public abstract class AbstractEntity {
#Column(nullable = false)
protected Date timeCreated;
#Column
private Long modifiedBy;
public AbstractEntity() {
super();
this.timeCreated = DateUtil.now();
this.modifiedBy = 0l;
}
public Date getTimeCreated() {
return timeCreated;
}
public void setTimeCreated(Date timeCreated) {
this.timeCreated = timeCreated;
}
#Override
public abstract String toString();
}
You can't define same column as more than times. If two columns present there, You need to mention insert = "false" and update = "false"
#Entity
#AssociationOverrides({ #AssociationOverride(name = "pk.user", joinColumns = #JoinColumn(name = "id")),
#AssociationOverride(name = "pk.role", joinColumns = #JoinColumn(name = "id", insertable = false, updatable = false)) })
public class UserRole extends AbstractEntity {
private UserRoleId pk;
public UserRole(User user, Role role) {
super();
this.pk = new UserRoleId(user, role);
}
#EmbeddedId
public UserRoleId getPk() {
return pk;
}
public Long getUserId() {
return pk.getUser().getId();
}
public Long getRoleId() {
return pk.getRole().getId();
}
}
Related
I make method (acceptUseroffermapping) in a REST-controller (UserOfferController) in which I want to delete record in the DB (UserOfferMapping table). But the problem is that record not deleted and relation also saved after I run this method.
I have also UserOfferMapping class which maps to User class. In UserOfferController I manipulate with UserOfferMapping: creating, selecting records from DB and also trying to delete records but have fail.
UserOfferController.java:
/*...*/
#POST
#RequestMapping("/acceptUserOfferMapping")
public void acceptUseroffermapping(#RequestBody Map<String,
String> body) throws ParseException {
String userId = body.get("userId");
String offerId = body.get("offerId");
Optional<User> user = userRepository.findById(Integer.parseInt(userId));
UserOfferMapping mapping = userOfferMappingRepository.getById(Integer.parseInt(userId));
user.get().getUserOfferMapping().remove(mapping);
userRepository.save(user.get());
userOfferMappingRepository.deleteById(Integer.parseInt(offerId));
}
/*...*/
User.java:
/*some imports*/
#Entity
#Table(name = "User")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int id;
/* ...
* a lot of fields
* ...
*/
// Important section which describes all Role Project and Skill mapping
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<UserUserrolemapping> userrolemapings = new HashSet<>();
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<Userprojectmapping> userprojectmappings = new HashSet<>();
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<UserOfferMapping> userOfferMapping = new HashSet<>();
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
#OrderBy
private Set<Userskillmapping> userskillmappings = new HashSet<>();
/* ...
* a lot of fields too
* ...
*/
/* getter and setters */
}
UserOfferMappingRepository.java:
public interface UserOfferMappingRepository extends JpaRepository<UserOfferMapping, Integer> {
public List<UserOfferMapping> getAllByUser(Optional<User> user);
public UserOfferMapping getUserOfferMappingByUserAndProjectAndUserRole(User user, Userproject userproject, Userrole userrole);
public UserOfferMapping getById(int id);
public void deleteById(int id);
}
UserOfferMapping.java:
#Entity
public class UserOfferMapping {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#ManyToOne
#JoinColumn(name = "userid")
#JsonBackReference
private User user;
#ManyToOne
#JoinColumn(name = "roleid")
private Userrole userRole;
#ManyToOne
#JoinColumn(name = "projectid")
private Userproject project;
#Column(name = "fromdate", nullable = true)
private Date fromdate;
#Column(name = "todate", nullable = true)
private Date todate;
#Column(name = "chance")
private int chance;
#Column(name = "percent")
private int percent;
public int getId() {
return id;
}
public User getUser() {
return user;
}
public Userrole getUserRole() {
return userRole;
}
public Userproject getProject() {
return project;
}
public Date getFromdate() {
return fromdate;
}
public int getChance() {
return chance;
}
public int getPercent() {
return percent;
}
public void setId(int id) {
this.id = id;
}
public void setUser(User user) {
this.user = user;
}
public void setUserRole(Userrole userRole) {
this.userRole = userRole;
}
public void setProject(Userproject project) {
this.project = project;
}
public void setFromdate(Date fromdate) {
this.fromdate = fromdate;
}
public void setChance(int chance) {
this.chance = chance;
}
public void setPercent(int percent) {
this.percent = percent;
}
public void setTodate(Date todate) {
this.todate = todate;
}
public Date getTodate() {
return todate;
}
}
Can you try to use this
public interface UserOfferMappingRepository extends JpaRepository<UserOfferMapping, Integer> {
public List<UserOfferMapping> getAllByUser(Optional<User> user);
public UserOfferMapping getUserOfferMappingByUserAndProjectAndUserRole(User user, Userproject userproject, Userrole userrole);
public UserOfferMapping getById(int id);
// public void deleteById(int id);
#Modifying(clearAutomatically = true)
#Query(value = "Delete from UserOfferMapping c WHERE c.id=:id")
public void deleteById(#Param("id") int id);
}
So, you have bidirectional entity association.
Try to add mapping.setUser(null); before userRepository.save.
Persisting and deleting objects requires a transaction in JPA so that is why you have to define #Transactional annotation before the method in Repository for example `
#Transactional
public void deleteById(#Param("id") int id);
I have a Spring project that uses JPA with Hibernate and MySQL database. Database includes three tables: Users, Roles, and many-to-many join table UserRoles.
Below are the corresponding classes for the tables.
ApplicationUser.java
#Entity
#Table(name = "APPLICATION_USER")
public class ApplicationUser extends ExtAuditInfo {
public static final Long SYSTEM_USERID = 1000L;
#Id
#Column(name = "APPLICATION_USER_ID")
private long applicationUserId;
#Column(name = "LOGIN_NAME")
private String loginName;
#Column(name = "LAST_NAME")
private String lastName;
#Column(name = "FIRST_NAME")
private String firstName;
#Column(name = "MIDDLE_NAME")
private String middleName;
#OneToMany(mappedBy = "id.applicationUser", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<UserRole> roles =new ArrayList<>();
//get and set methods
Role.java
#Entity
#Table(name = "ROLE")
#NamedQueries({
#NamedQuery(name = "Role.getRoleById", query = "select r from Role r where r.roleId =:roleId"))}
public class Role extends AuditInfo {
#Id
#Column(name="ROLE_ID")
private long roleId;
#Column(name="ACTIVE_FLAG")
private String activeFlag;
#Column(name="ROLE_NAME")
private String roleName;
#OneToMany(mappedBy = "id.role", fetch = FetchType.LAZY)
private List<UserRole> users = new ArrayList<>();
//get and set methods
UserRole.java
#Entity
#AssociationOverrides({
#AssociationOverride(name = "id.applicationUser",
joinColumns = #JoinColumn(name = "APPLICATION_USER_ID")),
#AssociationOverride(name = "id.role",
joinColumns = #JoinColumn(name = "ROLE_ID")) })
#Table(name = "USER_ROLE")
public class UserRole extends ExtAuditInfo implements Serializable{
#EmbeddedId
private UserRoleID id = new UserRoleID();
#Column(name="USER_ROLE_VER")
private long userRoleVer;
public UserRole(){
}
#Transient
public ApplicationUser getApplicationUser() {
return this.id.getApplicationUser();
}
public void setApplicationUser(ApplicationUser applicationUser) {
this.id.setApplicationUser(applicationUser);
}
public long getUserRoleVer() {
return this.userRoleVer;
}
public void setUserRoleVer(long userRoleVer) {
this.userRoleVer = userRoleVer;
}
#Transient
public Role getRole() { return this.id.getRole(); }
public void setRole(Role role) { this.id.setRole(role); }
}
UserRoleID.java
#Embeddable
public class UserRoleID implements Serializable {
#ManyToOne(cascade = CascadeType.ALL)
private ApplicationUser applicationUser;
#ManyToOne(cascade = CascadeType.ALL)
private Role role;
private static final long serialVersionUID = 1L;
public UserRoleID() {
}
public ApplicationUser getApplicationUser() {
return this.applicationUser;
}
public void setApplicationUser(ApplicationUser applicationUser) {
this.applicationUser = applicationUser;
}
public Role getRole() {
return this.role;
}
public void setRole(Role role) {
this.role = role;
}
}
Now, when I create a sample user with viewer role, the record is being inserted into the Application_user and User_Role tables, but when I try to update the role of the user it is adding a new role to the user instead of updating the existing role.
This is what I'm doing
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public void updateRole(ApplicationUser appUser, long roleId){
EntityManager em=getEntityManager();
TypedQuery<Role> query = em.createNamedQuery("Role.getRoleById", Role.class);
query.setParameter("roleId",roleId);
Role r = query.getSingleResult();
UserRole userRole= appUser.getRole().get(0);
userRole.setRole(r);
em.merge(userRole);
em.flush();
em.detach(userRole);
}
Any idea, what to do to update the existing role instead of creating a new role in user_role table?
You are assigning new role to user, so a new record is added in user_role table, and old user_role entry is deleted. That's the right behavior.
So it's not you called "update the role of user".
Update:
You should delete role manually when many-to-many relationship.
appUser.getRoles().remove(userRole);
em.remove(userRole);
UserRole newUserRole = new UserRole();
newUserRole.setRole(r);
appUser.getRoles().add(newUserRole);
I'm trying to generate Hibernate mapping to my H2 database.
I have 2 tables for test, called users and users_groups.
They look like:
users table:
user_id integer PK
login varchar
password varchar
user_group_id integer FK
users_groups
user_group_id integer PK
name varchar
And the problem is that hibernate generate entities like that:
#Entity
public class Users {
private int userId;
private int userGroupId;
#Id
#Column(name = "USER_ID", nullable = false)
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
#Basic
#Column(name = "USER_GROUP_ID", nullable = false)
public int getUserGroupId() {
return userGroupId;
}
public void setUserGroupId(int userGroupId) {
this.userGroupId = userGroupId;
}
#Entity
#Table(name = "USERS_GROUPS", schema = "PUBLIC", catalog = "DATABASE")
public class UsersGroups {
private int userGroupId;
#Id
#Column(name = "USER_GROUP_ID", nullable = false)
public int getUserGroupId() {
return userGroupId;
}
public void setUserGroupId(int userGroupId) {
this.userGroupId = userGroupId;
}
So no relation annotations are generated, like #OneToMany or #ManyToMany etc. What am I doing wrong? Thanks for your help.
p.s. I want it to generate mapping like
Users class with field of UserGroup type
If the classes were auto generated like this check your relation in the database between the two tables and make sure you choose the right schema your mapping is completely wrong the for example :-
1-the auto generated classes your mapping are missing some columns, class User doesn't contain password and login columns and class UsersGroups doesn't contain name column.
2- class User doesn't have #table annotation
They should look something like this :-
Class UserGroups
#Entity
#Table(name = "USERS_GROUPS", schema = "PUBLIC", catalog = "DATABASE")
public class UsersGroups implements java.io.Serializable {
private int userGroupId;
private String name;
private Set<Users> users = new HashSet<Users>(0);
public UsersGroups() {
}
#Id
#GeneratedValue(strategy = IDENTITY) //this to make the id auto increment
#Column(name = "user_group_id", nullable = false)
public int getUserGroupId() {
return userGroupId;
}
public void setUserGroupId(int userGroupId) {
this.userGroupId = userGroupId;
}
// if name column is not unique / nullable remove values from annotation
#Column(name = "name", unique = true, nullable = false, length = 10)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name= name;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "users_groups")
public Set<Users> getUsers() {
return this.users;
}
public void setUsers(Set<Users> users) {
this.users= users;
}
}
Class Users
#Entity
#Table(name = "users", schema ="PUBLIC" , catalog ="DATABASE")
public class Users implements java.io.Serializable {
private Integer userId;
private UsersGroups usersGroups;
private String password;
private String login;
public Users() {
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "user_id", unique = true, nullable = false)
public Integer getUserId() {
return this.userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "user_group_id", nullable = false)
public UsersGroups getUsersGroups() {
return this.usersGroups;
}
public void setUsersGroups(UsersGroups usersGroups) {
this.usersGroups = usersGroups;
}
#Column(name = "password",length = 10)
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "login",length = 10)
public String getLogin() {
return this.login;
}
public void setLogin(String login) {
this.login = login;
}
}
Check this full example for one to many mapping
So I have a one to many and many to one relation between two classes. When I try to update an entity, the parent is updated and child throws an error. In that case I expect the parent update to be rolled back but it is not. Since I have a one to many relation, an update on the parent is expected to insert a child but when the child throws an error shouldnt the parent's update be rolled back? If it is of any relation the child's error is thrown due to the unique constraints on the child/account entity.
Below are my two models:
/** User model **/
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, nullable = false)
private int id;
#Column(name = "type")
private String type;
#Column(name = "username", nullable = false)
private String username;
...
// define one to many relation between User and Account
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "user_id")
private Set<Account> accounts;
public User() {
}
#PrePersist
void preInsert() throws ParseException {
...
}
// field getters and setters
...
// returns Account list associated with User
public Set<Account> getAccount() {
return accounts;
}
// set Account list associated with User
public void setAccount(Set<Account> accounts) {
this.accounts = accounts;
}
}
Model 2:
/** Account model **/
#Entity
#Table(name = "account", uniqueConstraints =
#UniqueConstraint(columnNames = {"user_id", "entity_id", "branch_id", "type"}))
public class Account {
private int id;
#Column(name = "user_id", nullable = false)
private int user_id;
...
private User user;
// constructor
public Account() {
}
#PrePersist
void preInsert() throws ParseException {
...
}
// field getters and setters
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
...
// define many to one relation between Account and User
// get User associated with Account
#ManyToOne
#JoinColumn(name = "user_id", insertable = false, updatable = false)
public User getUser() {
return user;
}
// set User associated with Account
public void setUser(User user) {
this.user = user;
}
}
UserDAO:
#Repository("userDao")
#Transactional(propagation = Propagation.REQUIRED)
public class UserDAO {
#PersistenceContext
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void insert(User user) {
entityManager.persist(user);
}
public void update(User user) {
entityManager.merge(user);
}
....
}
User service (where i am calling the update)
#Service
public class UserService {
private UserDAO userDAO;
public UserDAO getUserDao() {
return userDAO;
}
#Autowired
public void setUserDao(UserDAO userDAO) {
this.userDAO = userDAO;
}
public boolean addUser(SignupComponent signupComponent) {
....
else {
// case (4)
// get user object
User userObj = getUserDao().findUser(user.getPhone());
// update user object, adding account and account details
Set<Account> accounts = userObj.getAccount();
Account a = new Account();
a.setBranch_id(signupComponent.branch_id);
a.setEntity_id(signupComponent.entity_id);
if (signupComponent.type != -1) {
a.setType(signupComponent.type);
}
a.setUser(userObj);
userObj.setAccount(accounts);
userObj.setEmail(signupComponent.user.getEmail());
AccountDetails ad = new AccountDetails(); //never mind this line, i have another one to one relation with another entity
ad.setAccount(a);
a.setAccountDetails(ad);
accounts.add(a);
try {
getUserDao().update(userObj);
return true;
}
catch(Exception e) {
signupComponent.error = e.toString();
return false;
}
}
}
}
You are defining JoinColumn at both the sides.You need to define at one side. How would it store an arbitrary number of foreign keys in a single row? Instead, it must let the tables of the entities in the collection have foreign keys back to the source entity table.
Try this:
public class User{
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL,mappedBy="user")
private Set<Account> accounts;
}
User class
/** User model **/
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, nullable = false)
private int id;
#Column(name = "type")
private String type;
#Column(name = "username", nullable = false)
private String username;
...
// FetchType should be Lazy to improve performance
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL,mappedBy="user")
private Set<Account> accounts;
//mappedBy says that this side is inverse side of relation and source is user which is mapped by user field name in Account class
public User() {
}
#PrePersist
void preInsert() throws ParseException {
...
}
// field getters and setters
...
// returns Account list associated with User
public Set<Account> getAccount() {
return accounts;
}
// set Account list associated with User
public void setAccount(Set<Account> accounts) {
this.accounts = accounts;
}
}
Account class
/** Account model **/
#Entity
#Table(name = "account", uniqueConstraints =
#UniqueConstraint(columnNames = {"user_id", "entity_id", "branch_id", "type"}))
public class Account {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
private int id;
#Column(name = "user_id", nullable = false)
private int user_id;
...
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name = "user_id", insertable = false, updatable = false)
private User user;
// constructor
public Account() {
}
#PrePersist
void preInsert() throws ParseException {
...
}
// field getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
...
// define many to one relation between Account and User
// get User associated with Account
public User getUser() {
return user;
}
// set User associated with Account
public void setUser(User user) {
this.user = user;
}
}
See now, when you save User then Account class will not be updated as User is at inverse side. But when you save Account class then user_id which is present in account table will get update as it is source side of relation.
I followed this tutorial to implement in my domain model a many-to-many relationship with an extra column. It works great but I'm unable to create a criteria to query a field within the left side of my relation.
Taking this code
#Entity
#Table( name = "projects")
public class Project implements Cloneable, Serializable{
private Long id;
private String name;
private Set<ProjectOrganization> projectOrganizations = new HashSet<ProjectOrganization>(0);
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false)
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "name", length = 255, nullable = false)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.project")
#Cascade(value = { CascadeType.ALL })
public Set<ProjectOrganization> getProjectOrganizations() {
return this.projectOrganizations;
}
public void setProjectOrganizations(Set<ProjectOrganization> organizationProjects) {
this.projectOrganizations = organizationProjects;
}
}
#Entity
#Table(name = "projects_has_organizations")
#AssociationOverrides({ #AssociationOverride(name = "pk.project", joinColumns = #JoinColumn(name = "projects_id")),
#AssociationOverride(name = "pk.organization", joinColumns = #JoinColumn(name = "organizations_id"))
})
public class ProjectOrganization implements Cloneable, Serializable {
private ProjectOrganizationPK pk = new ProjectOrganizationPK();
private OrganizationRolesEnum role;
public ProjectOrganization() {
}
#Transient
public Organization getOrganization() {
return getPk().getOrganization();
}
public void setOrganization(Organization organization) {
getPk().setOrganization(organization);
}
#EmbeddedId
public ProjectOrganizationPK getPk() {
return pk;
}
public void setPk(ProjectOrganizationPK pk) {
this.pk = pk;
}
#Transient
public Project getProject() {
return getPk().getProject();
}
public void setProject(Project project) {
getPk().setProject(project);
}
#Enumerated(EnumType.STRING)
#Column(nullable = false, length = 50)
public OrganizationRolesEnum getRole() {
return role;
}
public void setRole(OrganizationRolesEnum role) {
this.role = role;
}
}
#Embeddable
public class ProjectOrganizationPK implements Cloneable, Serializable {
/** Generated serial version UID */
private static final long serialVersionUID = -4534322563105003365L;
private Organization organization;
private Project project;
#ManyToOne
public Organization getOrganization() {
return organization;
}
public void setOrganization(Organization organization) {
this.organization = organization;
}
#ManyToOne
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
}
#Entity
#Table(name = "organizations")
public class Organization implements Cloneable, Serializable {
private Long id;
private String name;
private Set<ProjectOrganization> projectOrganizations = new HashSet<ProjectOrganization>(0);
public Organization() {
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false)
#Override
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "name", nullable = false, length = 255)
#NotNull(message = "A name is required!")
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.organization")
public Set<ProjectOrganization> getProjectOrganization() {
return this.projectOrganizations;
}
public void setProjectOrganization(Set<ProjectOrganization> projectOrganizations) {
this.projectOrganizations = projectOrganizations;
}
}
I want is to create a criteria to select a Project which has an organization with a requested name.
final Criteria crit = getSession().createCriteria(Project.class);
crit.createCriteria("projectOrganizations", "projectOrganization").
createAlias("pk.organization", "organization").
add( Restrictions.like("organization.name", "TEST"));
But when i run this code i have this error
2012-10-19 10:38:43,095 ERROR [org.hibernate.util.JDBCExceptionReporter] Unknown column 'organizati2_.name' in 'where clause'
and the sql query generated by hibernate is incomplete, doesn't join projects_has_organizations.organization with organization.id.. So it can't find column organization.name
SELECT
....
FROM
projects this_
INNER JOIN projects_has_organizations projectorg1_ ON this_.id = projectorg1_.projects_id
WHERE
projectorg1_.role =?
AND organizati2_. NAME LIKE ?
ORDER BY
this_.publish_date DESC
What's wrong with this code? How can i build query using criteria ?
I suspect that the problem is due to lazy fetching, try explicitly telling hibernate to eagerly fetch the property you need. This is done with the method
.setFetchMode("propertyName", FetchMode.EAGER)
So, in otherwords, try eagerly fetch the organisation property :)