I am creating a matchplay event for my Java Springboot application. This involves players playing each other player in the group once.
So far I have 3 classes, MatchPlay MatchPlayer and RoundRobin
MatchPlay holds details of the event (name etc) MatchPlayer holds details of the player who has entered, and RoundRobin holds all the matches which are to be played.
Each MatchPlayer is allocated to a group 1-3 and will play all other players in that group once. There are 4 players per group and so there will be 3 rounds of matches.
I am struggling with the RoundRobin class, so far my MatchPlay and MatchPlayer class look like this,
#Entity
#Table(name = "matchPlayer")
#IdClass(MatchPlayerId.class)
#Data
#EqualsAndHashCode(exclude = {"matchplay", "member"})
public class MatchPlayer {
#Id
#ManyToOne
#JoinColumn(name = "member_id", referencedColumnName = "id")
private Member member;
#Id
#ManyToOne
#JoinColumn(name = "matchplay_id", referencedColumnName = "id")
private Matchplay matchplay;
#Column(name = "points")
int points = 0;
#Column(name = "score")
int score = 0;
#Column(name = "grouping")
int grouping = 0;
public MatchPlayer() {}
public MatchPlayer(Member member, Matchplay matchplay) {
this.member = member;
this.matchplay = matchplay;
}
}
#Data
#EqualsAndHashCode
public class MatchPlayerId implements Serializable {
private long member;
private long matchplay;
}
#Entity
#Data
#NoArgsConstructor
#ToString
public class Matchplay {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
private String name;
#NotNull
private int year;
private String winner;
public Matchplay(Matchplay matchplay) {
this.setName(matchplay.getName());
this.setYear(matchplay.getYear());
}
/**
* Link a list of entrants to an event
*/
#JsonIgnore
#OneToMany(mappedBy = "matchplay", fetch = FetchType.LAZY)
private List<MatchPlayer> matchPlayer;
/**
* Link an event to a society
*/
#JsonIgnore
#ManyToOne
#JoinColumn(name = "society_id")
private Society society;
}
So far in my RoundRobin class, I have the following. I have used player1 and player2 to represent the member ID of each player
#Entity
#Table(name = "roundrobin")
#Data
public class RoundRobin {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(
name = "id",
updatable = false
)
private long id;
private long player1;
private long player2;
private int p1Score = 0;
private int p2Score = 0;
private int round;
public RoundRobin() {}
public RoundRobin(MatchPlayer p1Id, MatchPlayer p2Id, int round) {
this.setPlayer1(p1Id);
this.setPlayer2(p2Id);
this.setRound(round);
}
}
So far this works fine and I can show the output in my react frontend, showing the rounds to be played and the matches.
Obviously, I want the member names to be shown and not their ID number.
I am not sure how to setup the RoundRobin class so that it represents the actual MatchPlayer I when I get a list of all the RoundRobins for a matchplay, I want to be able to get the MatchPlayers for each RoundRobin` so that I can get their names and also the scores they have. So I can also then update the scores for each match.
Related
i want to implement a many to many association with quantity information in it . like this :
#Entity
#Table(name = "reserves")
#Getter #Setter #NoArgsConstructor
public class Reserve {
#Id
#ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn(name = "groupe_id")
private GroupeSanguin bloodGroup;
#Id
#ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
private Banque banque;
private int quantity;
}
the GroupSanguin and the Banque are two class stored in the database two . here is the code for the two if you need :
#Entity
#Table(name = "groupe_sanguins")
public class GroupeSanguin {
#Id
private String groupe;
#OneToMany(mappedBy = "groupeSanguin")
private List<Donneur> donneurs;
}
#Entity #Getter #Setter #NoArgsConstructor
public class Banque {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(unique = true,nullable = false)
private String nom;
private String adresse;
#Column(unique = true)
private String telephone;
private String localisation;
}
so my i want to know how to annotate the JpaRepository to take the two as primary key like this and is my annotation good for it to work ?
public interface ReserveRepository extends JpaRepository<
Reserve,
//what to put here ?
>
This isn't a JPA question in fact, it's a relationnal database conception.
If Reserve has is own data and links with other entity it has it own Id
You can add unicity constraint
#Entity
#Table(name = "reserves", uniqueConstraints={
#UniqueConstraint(columnNames = {"banque_id", "groupe_id"})
#Getter #Setter #NoArgsConstructor
public class Reserve {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn(name = "groupe_id")
private GroupeSanguin bloodGroup;
#ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn(name = "banque_id")
private Banque banque;
private int quantity;
}
i've found this solutions too.
#Entity
#Table(name = "reserves")
#Getter #Setter #NoArgsConstructor
#IdClass(ReserveId.class) //this annotation will tell that id that the
// the id will be represented by a class
public class Reserve {
#Id
#ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn(name = "groupe_id")
private GroupeSanguin groupeSanguin;
#Id
#ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn(name = "banque_id")
private Banque banque;
private int quantity;
}
and the id class should implements Serializable like this :
#Getter #Setter
public class ReserveId implements Serializable {
private Banque banque;
private GroupeSanguin groupeSanguin;
}
and finally the repository will be like that :
#Repository
public interface ReserveRepo extends JpaRepository<Reserve, ReserveId>{}
See your Reserve class has nowhere mentioned composite primary key. First you need to fix the model, You can refer to the solution here How to create and handle composite primary key in JPA
I need to fetch names of all students who have enrolled for the courses.
Url:-/students/{course1}/{course2}
Eg /students/java/oracle
How to write controller, service and repository in rest api.
Entity:-
Student
Integer Id,String name and list coursenames
What about?
#Controller
#RequestMapping("/students")
public class StudentController {
#Autowired
private StudentService studentService;
// /students/java,oracle
#GetMapping(value="/{courses}")
#ResponseBody
public String getStudents(#PathVariable String[] courses) {
return studentService.getStudents(courses);
}
}
Student
#Entity
#Table(name = "student")
public class StudentDao {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToMany(fetch = FetchType.EAGER)
#Fetch(value = FetchMode.SUBSELECT)
#JoinColumn(name = "id", referencedColumnName = "id")
private List<CourseDao> course;
}
Course
#Entity
#Table(name = "course")
public class CourseDao {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
}
In my opinion it is bad rest design. I'll create POST endpoint with body, which contains array with course Id's and find students by course id's.
If the parameters are optional or an array you shouldn't use a path variable but use a request parameter.
Procedure.java
#Entity
#Table(name = "procedures")
#JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
public class Procedure implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ProcedureId")
private int id;
#Column(name = "ProcedureName")
private String name;
#Column(name = "ProcedureCode")
private String code;
#Column(name = "ProcedureDesc")
private String desc;
// getters and setters
}
CPTClinicianDescriptor
#Entity
#Table(name = "cliniciandescriptor")
public class CPTClinicianDescriptor {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "Id")
private int id;
#Column(name = "ConceptId")
private int conceptId;
#Column(name = "CPTCode")
private String cptCode;
#Column(name = "ClinicianDescriptorId")
private int clinicianDescriptorId;
#Column(name = "ClinicianDescriptor")
private String clinicianDescriptor;
// getters and setters
}
CPTProcedures
#Entity
#Table(name = "cptprocedures")
public class CPTProcedures {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "Id")
private int Id;
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "ProcedureId")
private Procedure procedure;
#Transient
private int procedureId;
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "CPTCodeSet")
private CPTClinicianDescriptor cptClinicianDescriptor;
#Transient
private int cptCodeSet;
// getters and setters
}
Here I have 3 table in mySql in those 2 are different separate tables, I created one table for Mapping that has foreign keys of Procedures and CPT when i get a list using Procedure It should get corresponding cpt data also.
ServiceImpl Like:
public List<Procedure> getCombinedProcedureList(int id) {
// TODO Auto-generated method stub
List<Procedure> pList = new ArrayList<Procedure>();
Procedure procedureList = procedureRepository.findCombById(id);
pList.add(procedureList);
return pList;
}
When i use
Repository like
#Query(value = "SELECT * FROM procedures JOIN cliniciandescriptor ON cliniciandescriptor.Id = ?1",nativeQuery = true)
Procedure findCombById(int id);
this query in Procedures Repository it is getting only procedures. So, what can i do to get the combined(joined) list of 2(procedures & CPT) tables using 3rd mapping table.
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);
}
I have created two Entities namely Teacher and Detail, the code snippet is shown below
Teacher.java
#Entity
#Table(name = "teacher")
public class Teacher implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#Column(name = "name")
private String name;
#Column(name = "age")
private int age;
#OneToOne(mappedBy = "teacher", cascade = CascadeType.ALL)
private Detail detail;
public Teacher() {
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
//getter and setter
}
Detail.java
#Entity
#Table(name = "detail")
public class Detail implements Serializable {
#Id
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "id")
private Teacher teacher;
#Column(name = "subjects")
private String subjects;
public Detail() {
}
public Detail(String subjects) {
this.subjects = subjects;
}
//getter and setter
}
I am trying to achieve one to one mapping with the shared primary key concept
but when i execute the controller, only Teacher table is updating with the value
try {
Teacher teacher=new Teacher("xyz",23);
Detail detail=new Detail("Java,c,c++");
teacher.setDetail(detail);
session.beginTransaction();
session.save(teacher);
session.getTransaction().commit();
model.addAttribute("added", "data inserted");
session.close();
}
After executing only Teacher table is updated with the specified values.Detail table is still showing empty
It does not work exactly like that. You still need the id field in your Detail, so add:
#Id
private long id;
to your Deatail class.
And - as comment suggests - replace the #Id annotation in field Teacher to #MapsId. This way the id of Teacher is mapped to the id of Detail BUT ONLY if you also set the teacher to the detail - you always need to set both sides of relationship - like:
teacher.setDetail(detail);
detail.setTeacher(teacher);