#ManyToMany with extra column - how to load via Spring Data? - spring

I have many to many relation between User and Event. I need to have extra column in relational table. I did id:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#OneToMany(mappedBy="user")
private Set<EventUser> eventUsers = new HashSet<>();
//
}
#Entity
public class Event {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private long id;
#OneToMany(mappedBy="event")
private Set<EventUser> eventUsers = new HashSet<>();
//
}
#Entity
#Table(name = "Event_User")
public class EventUser {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private long id;
private String reaction;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "user_id")
private User user;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "event_id")
private Event event;
//
}
But now... I don't know how to load all events where user has concrete email. Before it I used method:
findByUsersEmail(String email);
Now I can't do this, because Event doesn't have Set users field.
Any ideas ?

What you need here is property-expressions.
Just a quick idea to start:
findByEventUsers_UserEmail(String email);
Note: Dont forget that creating queries by method names is a very limited approach and only used by trivial cases. In any other case, don't be afraid of using the #Query annotation on the method or write JPQL/Criteria API manually.

Related

Save entity with realtion

I have two entities with one-to-mane relationship:
#Entity
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Long id;
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
#JsonManagedReference
private List<RealEstate> realEstates = new ArrayList<>();
#Entity
public class RealEstate implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String name;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "user_id")
#JsonBackReference
private User user;
I try to save realEstate entity with this code:
realEstate.setUser(user);
realEstateService.saveRealEstate(realEstate);
And this response:
[
{
"id": 1,
"name" : "Bueno",
"user" : 1
}
]
By all I have is creating new record in user table and relation with this new ID.
What I do wrong? What I need to read about this?
You first need to save User entity record and then RealEstate entity record.
Please read this article to implement One To Many relationship. I am sure your issue will be resolved.
https://attacomsian.com/blog/spring-data-jpa-one-to-many-mapping

JPA onetomany mapping showing nested data many times

I have two table user(id,name) and user_mails(id,email,user_id) user to user_mails have one to many relation.
I have created following entity in spring boot
User
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int id;
#Column(name = "name", nullable = false)
private String name;
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private Set<UserMail> userMails =new HashSet<UserMail>(0);
//Getter setter and constructor
}
UserMail
#Entity
#Table(name = "user_mails")
public class UserMail {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "email", nullable = false)
private String name;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "user_id")
private User user;
It is showing following output on calling controller
[{"id":1,"name":"Ram","userMails":[{"id":2,"name":"ram#b.com","user":{"id":1,"name":"Ram","userMails":[{"id":2,"name":"ram#b.com","user":{"id":1,"name":"Ram","userMails":[{"id":2,"name":"ram#b.com","user":{"id":1,"name":"Ram","userMails":[{"id":2,"name":"ram#b.com","user":{"id":1,"name":"Ram","userMails":[{"id":2,"name":"ram#b.com","user":{"id":1,"name":"Ram","userMails":[{"id":2,"name":"ram#b.com","user":{"id":1,"name":"Ram","userMails":
and more
I want to access all users with all mail ids also want to acces mail id with user details
What changes should I do to get proper result

Troubles with Bidirectional One-To-One JPA

I'm coding a CRUD JPA web application. My goal is that a given parent Vehicle can only have a single child Driver, but during runtime this same Driver can instead be assigned to another Vehicle and vice versa. To my understanding, this could be accomplished via an OneToOne relationship.
I've tried some different approaches, but to no success. I can assign a Vehicle to a Driver just fine, but when I try to update/create a new Vehicle and give him a Driver, via controllers, nothing happens. I can only do it the other way around. I'm assuming this is because Vehicle is the parent and I can only create a new relation by updating a parent.
My question is, is it possible to make these updates bidirectional and how can I achieve that?
I've tried using a shared primary key, using a foreign key, using a join table. The result is always the same and I can't quite grasp why. I have an OneToMany relationship working on this application and it works as I expect it to work. I can update on one side or the other, delete on one side or the other. Both entities have been updated. OneToOne? Parent seems to have all the power.
This is what I'm working with right now:
Driver
#Entity
#Table(name= "drivers")
public class Driver {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private int age;
#OneToOne(mappedBy = "driver")
private Vehicle vehicle;
Vehicle
#Entity
#Table(name= "vehicles")
public class Vehicle {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(nullable = false)
private String make;
#Column(nullable = false)
private String model;
#Column(nullable = false)
private int mileage;
#Column(nullable = false)
private int year;
#Column(nullable = false)
private int fuel;
#OneToOne
#JoinColumn(name = "driver_id")
private Driver driver;
And just for reference, this is the OneToMany relationship I have and that I'm happy with. I'd like my OneToOne to have the same behavior, except I don't need to save a list of entities, only one.
#Entity
#Table(name="stops")
public class Stop {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(nullable = false)
private String name;
#ManyToOne
#JoinColumn(name="route_id")
private Route route;
#Entity
#Table(name="routes")
public class Route {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(nullable = false)
private String name;
#OneToMany
#JoinColumn(name = "route_id")
private List<Stop> stops = new ArrayList<>();
Any tips would be appreciated, thank you for your time.

JPA one to many, fetch children with specific column value

I have two entities in one to many relationship in my spring-data-jpa project.
Parent entity -
#Entity
#Table(name = "code_group")
public class CodeGroup implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
#NaturalId
#Column(nullable = false)
private String entityId;
#OneToMany
#JoinColumn(name = "codeGroupId", referencedColumnName = "entityId")
private List<SystemCode> systemCodes;
// .. getters setters
}
Child entity -
#Entity
#Table(name = "system_code")
public class SystemCode implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
#Column(nullable = false)
private String codeGroupId;
#Column(nullable = false)
#Enumerated(EnumType.STRING)
private ActiveOrInactive status;
// getters and setters
}
status column is of enum type, it can only have Active or Inactive value.
My existing code works fine. It is fetching code group with associated system codes. I want to filter system code with status='Active'. How to do this?
Try like this:
#OneToMany
#JoinColumn(name = "codeGroupId", referencedColumnName = "entityId")
#Where(clause = "status= 'Active'")
private List<SystemCode> systemCodes;
You can create such methods in your repo:
List<CodeGroup> getAllBySystemCodes_Status(ActiveOrInactive status);
default List<CodeGroup> getAllActive() {
return getAllBySystemCodes_Status(ActiveOrInactive.Active);
}
default List<CodeGroup> getAllInactive() {
return getAllBySystemCodes_Status(ActiveOrInactive.Inactive);
}

Return an empty list on #OneToMany SpringBoot - Hibernate

I am getting null when using relationship in hibernate.
Here is my code
User entity
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private long userId;
#OneToMany(mappedBy="user",targetEntity=LoginHistory.class, fetch=FetchType.LAZY,cascade = CascadeType.ALL)
private List<LoginHistory> loginHistory = new ArrayList<LoginHistory>();
LoginHistory Entity
#Entity
#Table(name = "login_history")
public class LoginHistory {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#ManyToOne(cascade = CascadeType.DETACH)
#JoinColumn(name="userId",referencedColumnName="id")
private User user;
To get login history details
#Override
public List<LoginHistory> getLoginHistory(User user) {
List<LoginHistory> lst = user.getLoginHistory();
return lst;
}
I am getting an empty list. Please help
it is working as designed as you are accessing an entity which is lazy loaded.Use the below like code to get the login history if you continue to keep the lazy loading on.
User user = getByKey(id);
if(user!=null){
Hibernate.initialize(user.getUserProfiles());
}

Resources