I am using spring boot data jpa 1.4 and I'm fairly new to it.
My table definition is here. Its fairly simple, there are 2 tables (Groups and Users).
The group table contains group_id(primary key), group_name, group_active(values=Y/N).
The group table can ideally have only one row which is has group_active to 'Y', the rest should have 'N'
The user table contains user_id(primary key), user_name, group_id(foreign key from group).
Following are my entity classes
Group:
#Entity
#Table(schema = "HR", name = "GROUPS")
public class Group {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "GROUP_ID")
private Long id;
#Column(name = "GROUP_NAME")
private String name;
#Column(name = "GROUP_ACTIVE")
private String active;
User:
#Entity
#Table(schema = "HR", name = "USERS")
public class User {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "USER_ID")
private Long id;
#Column(name = "USER_NAME")
private String name;
#Column(name = "GROUP_ID")
private Long groupId;
#ManyToMany
#JoinTable(
schema = "HR",
name = "GROUPS",
joinColumns = {#JoinColumn(table = "GROUPS", name = "GROUP_ID", insertable = false, updatable = false)},
inverseJoinColumns = {#JoinColumn(table = "USERS", name = "GROUP_ID", insertable = false, updatable = false)}
)
#WhereJoinTable(clause = "GROUP_ACTIVE='Y'")
private List<Group> group;
Repository class:
public interface UserRepository extends CrudRepository<User, Long>{
List<User> findByName (String name);
}
Query: This is the query I want to execute, which is a simple inner join.
SELECT U.*
FROM HR.USER U, HR.GROUP G
WHERE U.GROUP_ID=G.GROUP_ID
AND G.GROUP_ACTIVE='Y'
AND U.USER_NAME=?
What would be the correct way to write the #JoinTable or #JoinColumn such that I always get back one user that belongs to the active group with the name ?
I have done some tests based on your set-up and the solution would need to use filters (assuming there is only one Group with Group_Activity = 'Y'):
Group Entity
#Entity
#Table(schema = "HR", name = "GROUPS")
public class Group {
#OneToMany(mappedBy = "group")
#Filter(name = "activityFilter")
private Set<User> users;
User Entity
#Entity
#Table(schema = "HR", name = "USERS")
#FilterDef(name="activityFilter"
, defaultCondition="group_id =
(select g.id from groups g where g.GROUP_ACTIVE='Y')")
public class User {
#ManyToOne
#JoinColumn(name = "group_id")
private Group group;
When making a query
session.enableFilter("activityFilter");
session.createQuery("select u from Group g inner join g.users u where u.user_name = :userName");
Additionally if there are many groups with activity = 'Y' then try this:
#FilterDef(name="activityFilter"
, defaultCondition="group_id in
(select g.id from group g where g.GROUP_ACTIVE='Y')")
Related
I have a repo with a unique constraint on 2 fields, connection_id and token_type:
#Entity
#Table(
name = "business_api_token",
schema = "public",
uniqueConstraints = {
#UniqueConstraint(
name = "business_api_token_unique_connection_id_and_token_type",
columnNames = {"connection_id", "token_type"}
)
}
)
public class BusinessApiToken {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToOne
#JoinColumn(
name = "connection_id",
nullable = false,
foreignKey = #ForeignKey(
name = "fk_business_api_token_connection_id"
)
)
private AccountingConnection connection;
#Column(name = "token_type")
#Enumerated(EnumType.STRING)
private ApiTokenType tokenType;
#Column(name = "token_value")
private String tokenValue;
...
}
I saw some posts saying add a custom query, something like this:
#Modifying
#Query("update User u set u.firstname = ?1, u.lastname = ?2 where u.id = ?3")
void setUserInfoById(String firstname, String lastname, Integer userId);
But how would I do this for a list? I was doing this:
businessApiTokenRepository.saveAll(tokens)
Which gives an error.
The tokens are created elsewhere without knowledge of existing ones, I can do another query to check first but that seems inefficient, and I have to do this all over.
Thanks
I have 2 entities and want to perform an inner join on the ID of these two tables. How do I do that? After joining the tables, how do I get the values?
First entity: Employee.java
#Entity
#Table(name = "emp")
public class Employee {
#Id
#Column(name = "id", nullable = false)
private int id;
#Column(name = "language", nullable = false)
private String language;
Second entity: Username.java
#Entity
#Table(name = "users")
public class Username {
#Id
#Column(name = "id", nullable = false)
private int id;
#Column(name = "name", nullable = false)
private String name;
Thanks
I don't know it's helpful for your or not but,
You have to give relationship between those table first(Here i defined bidirectional relationship).
I suppose there is #OneToOne mapping. As like follow,
In Employee Table,
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "username_id")
private Username username;
#OneToOne(mappedBy = "employee")
private Employee employee;
Same way whenever you need those data base on requirement then Place Query as following way in your Employee Repository,
#Query(nativeQuery = true, value="<your-join-query>")
public Employee getEmployeeAllDetails();
For more brief detail follow this kind of tutorials which give you better idea regurding working mechenisum.
https://howtodoinjava.com/
https://www.baeldung.com/
I Have below Entities :
#Entity(name = "USRGRP_MAP")
public class UserGroupMapping {
#Id
#Column(name = "USRGRP_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_GRP_MAP_SEQ")
#SequenceGenerator(sequenceName = "usrgrp_map_seq",allocationSize = 1,name = "USER_GRP_MAP_SEQ")
private Long mappingId;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID")
private User user;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "USR_GRP_ID", referencedColumnName = "USR_GRP_ID")
private UserGroup group;
#Column(name = "USR_USRGRP_ACT")
private String userGroupAct;
getter/setters
}
#Entity(name = "USER")
public class User {
#Id
#Column(name = "USER_ID")
private Long userId;
#Column(name = "LOGIN_ID")
private String userName;
getter/setters
}
#Entity(name = "USR_GRP")
public class UserGroup {
#Id
#Column(name = "USR_GRP_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_GRP_SEQ")
#SequenceGenerator(sequenceName = "usr_grp_seq",allocationSize = 1,name = "USER_GRP_SEQ")
private long groupId;
#Column(name = "GRP_NM")
private String groupName;
#Column(name = "GRP_DESC")
private String groupDesc;
getter/setters
}
UserGroupMapping contains has many to one relationship with both user and group.
Now I want to do CRUD operation on UserGroupMapping for that I have created repository as below:
public interface UserGroupMappingRepository extends JpaRepository<UserGroupMapping, Long> {
List<UserGroupMapping> findByGroup(UserGroup group);
List<UserGroupMapping> findByUser(User user);
}
Now I want to write delete operation(for particular user and group) on UserGroupMapping without deleting any entry in USER and USR_GRP table , Just need to remove entry from USRGRP_MAP table.
I am trying to achieve it using native query:
#Query(value = "delete from USR_USRGRP_MAP where user_id = :userId and usr_grp_id = :groupId",nativeQuery = true)
void deleteUserGroupMappingByUserAndGroup(#Param("userId") Long userId, #Param("groupId") Long groupId);
Facing Exception Invalid SQL grammar, although query work fine in sql developer.
Below is my service class:
#Service
public class UserGroupMappingServiceImpl implements UserGroupMappingService{
#Autowired
private UserGroupMappingRepository repository;
#Override
public void deleteUserGroupMapping(Long userId, Long groupId) {
repository.deleteUserGroupMappingByUserAndGroup(userId,groupId);
}
}
Could anyone suggest correct way to delete entry from UserGroupMapping without deleting user and group ?
Below is USRGRP_MAP table:
USRGRP_ID USER_ID USR_USRGRP_ID USR_USRGRP_ACT
------------- ---------- ------------- -
41 306106 41 Y
14 108527 14 Y
8 295597 8 N
10 296518 10 Y
11 295597 11 Y
Thanks in advance .
Try to change
#Query(value = "delete from USR_USRGRP_MAP where user_id = :userId and usr_grp_id = :groupId",nativeQuery = true)
void deleteUserGroupMappingByUserAndGroup(#Param("userId") Long userId, #Param("groupId") Long groupId);
To this:
#Modifying
#Query(value = "delete from USR_USRGRP_MAP where user_id = :userId and usr_grp_id = :groupId",nativeQuery = true)
void deleteUserGroupMappingByUserAndGroup(#Param("userId") Long userId, #Param("groupId") Long groupId);
Cheers
~Emil
I am having below tables here but having some problem while fetching results.
#Entity
#Table(name = "USER_VW")
public class WorkspaceUserImpl
{
#JoinColumn(name = "USER_ID", insertable=false, updatable=false)
#OneToOne(targetEntity = UserImpl.class, fetch = FetchType.EAGER)
private User user;
}
#Table(name = "IK_USER")
#Inheritance(strategy = InheritanceType.JOINED)
#AttributeOverride(name = "id", column = #Column(name = "USER_ID") )
public class UserImpl extends BaseAuditable<UserIdentifier>implements User, UserAuthentication {
private static Logger log = LoggerFactory.getLogger(UserImpl.class);
#Id
#Type(type = "com.commons.UserIdentifierTypeMapper")
#Column(name = "USER_ID")
private UserIdentifier id;
}
and User
Public Inteface User
{
UserIdentifier getId();
}
Now i have written an HQL query to fetch all the data from WorkspaceUserImpl class with a given user ID for UserImpl class like below.
SELECT w from WorkspaceUserImpl w where w.user.id = : user_id;
and also tried
SELECT w from WorkspaceUserImpl as w INNER JOIN w.user as u where u.id = : user_id;
and even tried with JOIN FETCH also
and setting the parameter user_id with some say 1234.
but am getting List as emply for the partcular ID but in DB its having 5 records.
am i making any query mistake here? kindly advice..
Have you tried below query:
from WorkspaceUserImpl as w JOIN FETCH w.user as u where u.id = : user_id;
I'm using JPA 2.0, Hibernate 4.1.0.Final, and Spring 3.1.1.RELEASE. I have two entities:
#Entity
#Table(name = "user",
uniqueConstraints = { #UniqueConstraint(columnNames = { "USER_NAME" }) }
)
public class User implements Comparable<User>, Serializable
{
...
#Column(name = "first_name")
#NotNull
/* the first name of the User */
private String firstName;
and
#Entity
#Table(name="code_user",
uniqueConstraints = {
#UniqueConstraint(columnNames = { "SAMPLE_WORD_ID", "USER_ID" }) }
)
public class CodeUser
{
#Id
#NotNull
#GeneratedValue(generator = "uuid-strategy")
#Column(name = "ID")
private String id;
#ManyToOne
#JoinColumn(name = "CODE_ID", nullable = false, updatable = true)
private Code code;
#ManyToOne
#JoinColumn(name = "USER_ID", nullable = false, updatable = true)
private User user;
How do I write a JPA/CriteriaBuilder query to find all User objects who's first name matches "Dave" and who are tied to a Code record in which the code is "abode"?
I might have missed an HQL syntax element
SELECT user FROM CodeUser codeUser
JOIN FETCH codeUser.user user
JOIN FETCH codeUser.code code
WHERE user.firstName = 'Dave' AND code.value = 'abode'
assuming Code has a field value holding the value "abode". You might not need the FETCH.
You can always replace the literal values with a placeholder like ? or a named placeholder like :name and set their values from the Query object.