I'm making a DBMS application where I would add a Donor, Donation, and MOA (Memorandum of Agreement) row entry. What I want to accomplish with this application is when I add those three rows using inputs from my frontend and press a button those three would automatically link up together.
Here is the ERD for the relationship. It's a classic many to many with a bridge type of relationship.
The Code
Donor.java
public class Donor extends Auditable implements Comparable<Donor>{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotBlank(message = "Cannot have an empty account number field.")
private String accountNumber;
private String accountName;
private String donorName;
private String companyTIN;
private String companyAddress;
private String address1;
private String address2;
private String address3;
private String address4;
private String address5;
private String phone1;
private String phone2;
private String faxNumber;
private String cellphoneNumber;
private String emailAddress;
private String salutation;
private LocalDate birthDate;
private String notes;
#OneToMany(mappedBy = "donor")
List<MOA> moaList = new ArrayList<>();
...
MOA.java
public class Donor extends Auditable implements Comparable<Donor>{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotBlank(message = "Cannot have an empty account number field.")
private String accountNumber;
private String accountName;
private String donorName;
private String companyTIN;
private String companyAddress;
private String address1;
private String address2;
private String address3;
private String address4;
private String address5;
private String phone1;
private String phone2;
private String faxNumber;
private String cellphoneNumber;
private String emailAddress;
private String salutation;
private LocalDate birthDate;
private String notes;
#OneToMany(mappedBy = "donor")
List<MOA> moaList = new ArrayList<>();
...
Donation.java
public class Donation extends Auditable implements Comparable<Donation> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotBlank(message = "Cannot have an empty account number field.")
private String accountNumber;
private String accountName;
private String orNumber;
private String date;
private Double amount;
private String notes;
private String needCertificate;
private String purposeOfDonation;
#OneToMany(mappedBy = "donation")
List<MOA> moaList = new ArrayList<>();
...
What should I write on one of my services to have this feature of being able to sync the tables together?
Try this:
public class Donor extends Auditable implements Comparable<Donor>{
...
#OneToMany(mappedBy = "donor")
List<MOA> moaList = new ArrayList<>();
public class MOA {
...
#ManyToOne
private Donor donot;
#ManyToOne
private Donation donation;
...
public class Donation extends Auditable implements Comparable<Donation> {
...
#OneToMany(mappedBy = "donation")
List<MOA> moaList = new ArrayList<>();
...
public class MOA {
...
#ManyToOne
private Donor donor;
#ManyToOne
private Donation donation;
//getters and setters
public addDonor(Donor donor){
this.setDonor(donor);
}
public addDonation(Donation donation){
this.setDonation(donation);
}
}
For linking up all the three entities
MOA moa = new MOA();
Donor donor = new Donor();
Donation donation =new Donation();
//enter the values for fields in donor, donation,moa class by using setter methods
moa.setDonor(donor);
moa.setDonation(donation);//by setting these values all three entities will be saved.
Related
From Postman I perform the query to the secondary table and the primary field of the parent table is not shown:
view image:
I need to see: identification_number
This is the daughter table:
#Entity
#Table(name="accounts")
public class Account {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long account_number;
private Date open_date;
private byte status;
private String account_type;// normalizar
private String bank;// normalizar
#JsonBackReference
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="identification_number")
private Customer customer = new Customer();
This is the parent table:
#Entity
#Table(name="customers")
public class Customer implements Serializable{
private static final long serialVersionUID = 1L;
#Id
private String identification_number;
private String identification_type;//Normalizado
private String name;
private String last_name;
private String email;
private String cell_phone_number;
private String address;
#JsonManagedReference
#OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
//private List <Account> account = new ArrayList<>();
private Set<Account> account = new HashSet<Account>();
please help
I have got 3 entity. These are: Tweet,Thread and Media. I am using Hibernate JPA Annotations. When i save one Thread object, it must trigger to tweet and automatically tweet must saved like thread and Tweet's "media" must saved of course.
You can see my entity class as below. Right now i'm working on Tweet beetween Thread. When i use these code, The number of thread is being recorded as much as tweet object. But i want that only one record inside thread.
Process must be like that after saved thread:
add a new record to Thread table. (only one row)
add all tweet to tweet table(all of "threadid" column same because these tweets belong only one thread!)
add all media to media table(all of "tweetid" column same )
Tweet Table:
#Entity
#Table(name = "tbl_tweet")
public class Tweet implements Serializable {
#Id
#GeneratedValue
private long id;
#Column(name = "tweetid")
private String tweetID;
private String parentTweetID;
private String avatar;
private String owner_name;
private String owner_nick;
private String content;
private String sent_time;
private String sent_date;
private String retweet_count;
private String like_count;
private String owner_link;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="threadid")
private Thread thread;
#OneToMany(mappedBy = "tweet",fetch = FetchType.LAZY,cascade = {CascadeType.PERSIST,CascadeType.MERGE})
private List<Media> mediaURLs;
Thread Table:
#Entity
#Table(name = "tbl_thread")
public class Thread implements Serializable {
#Id
#GeneratedValue
private Long id;
#Column(name = "threadid")
private String threadID;
#Transient
private List<Tweet> listOfTweets;
Media Table:
#Entity
#Table(name = "tbl_media")
public class Media implements Serializable {
#Id
#GeneratedValue
private long id;
private String mediaID;
private String mediaType;
private String mediaUrl;
private String mediaUrlHttps;
private String mediaVideoUrl;
#ManyToOne
#JoinColumn(name = "tweetid")
private Tweet tweet;
My expected and actual results:
http://prntscr.com/mkaul5
I changed that way. Right now it's working good. Long live annotations!
Tweet Table:
#Entity
#Table(name = "tbl_tweet")
public class Tweet implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(unique = true,nullable = false,name = "tweetID")
private String tweetID;
private String parentTweetID;
private String avatar;
private long owner_id;
private String owner_name;
private String owner_nick;
private String content;
private String sent_time;
private String sent_date;
private String retweet_count;
private String like_count;
#Transient
private String quotedTweetHtml;
#Transient
#JoinColumn(name = "threadid",referencedColumnName = "id")
private Thread thread;
#OneToMany(cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)
#JoinColumn(name = "tweetID")
private List<Media> mediaURLs;
Thread Table:
#Entity
#Table(name = "tbl_thread")
public class Thread implements Serializable {
#Id
#GeneratedValue
private Long id;
#Column(name = "threadid")
private String threadID;
#OneToMany(cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)
#JoinColumn(name = "threadid")
private List<Tweet> listOfTweets;
Media Table:
#Entity
#Table(name = "tbl_media")
public class Media implements Serializable {
#Id
#GeneratedValue
private long id;
private String mediaID;
private String mediaType;
private String mediaUrl;
private String mediaUrlHttps;
private String mediaVideoUrl;
#Transient
#JoinColumn(name = "tweetID")
private Tweet tweet;
I have two tables with primary keys questionNumber and assessmentId. I want to use these two to make them composite in two different tables. Is this possible. Should I add something to this to make it work. OR is there another way to implement it. OR should I add question meta data to question and just used the composite key in AnswerKey
Question
#Entity
#Getter
#Setter
public class Question implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int questionId;
private int questionNumber;
private String assessmentId;
private QuestionTypes questionType;
private String questionText;
private String questionURL;
private QuestionStatus questionStatus;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "questionNumber", referencedColumnName = "questionNumber")
private List<QuestionOption> questionOptions;
//Constructor
// Getter and setter
}
Assessment
#Entity
#JsonIgnoreProperties({"questionList"})
public class Assessment {
#Id
private String assessmentId;
private String assessmentTopic;
private String assessmentSubTopic;
private String assessmentLevel;
private String createdBy;
private String rating;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "assessmentId", fetch = FetchType.LAZY)
private List<Question> questionList;
//Constructor
//Setter and getter
}
QuestionMetaData
#Entity
public class QuestionMetaData {
#Id
private QuestionAssessmentKey questionAssessmentKey;
private String topicName;
private String subtopicName;
private QuestionComplexity complexity;
private String conceptName;
//Getter and setter
//Constructor
}
AnswerKey
#Entity
public class AnswerKey {
#Id
private QuestionAssessmentKey questionAssessmentKey;
private Character answer;
//Constructor
// Setter and getter
}
Key
#Embeddable
public class QuestionAssessmentKey implements Serializable {
private int questionNumber;
private String assessmentId;
//Constructor
//Setter and Getter
}
These are "derived identities", so your mappings should like this:
#Entity
public class Assessment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private String assessmentId;
private String assessmentTopic;
private String assessmentSubTopic;
private String assessmentLevel;
private String createdBy;
private String rating;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "assessment", fetch = FetchType.LAZY)
private List<Question> questionList;
// ...
}
#Entity
public class Question implements Serializable {
#EmbeddedId
private QuestionAssessmentKey questionAssessmentKey;
#ManyToOne
#MapsId("assessmentId") // maps assessmentId attribute of embedded id
private Assessment assessment;
private QuestionTypes questionType;
private String questionText;
private String questionURL;
private QuestionStatus questionStatus;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "questionNumber", referencedColumnName = "questionNumber")
private List<QuestionOption> questionOptions;
// ...
}
#Entity
public class QuestionMetaData {
#EmbeddedId
private QuestionAssessmentKey questionAssessmentKey;
private String topicName;
private String subtopicName;
private QuestionComplexity complexity;
private String conceptName;
#ManyToOne
#MapsId("assessmentId") // maps assessmentId attribute of embedded id
private Assessment assessment;
// ...
}
#Entity
public class AnswerKey {
#EmbeddedId
private QuestionAssessmentKey questionAssessmentKey;
private Character answer;
#ManyToOne
#MapsId("assessmentId") // maps assessmentId attribute of embedded id
private Assessment assessment;
// ...
}
#Embeddable
public class QuestionAssessmentKey implements Serializable {
private String assessmentId;
private int questionNumber;
// ...
}
I have a many to many mapping: users and rooms, as follow:
User.java
#Entity
#Table(name="users", indexes = {
#Index(unique=true, columnList="uid"),
#Index(unique=true, columnList="backendAccessToken"),
#Index(columnList="backendAccessToken", name="idx_backend")
})
public class User extends BasePersistable {
private static final long serialVersionUID = 1492535311821424305L;
#Column(nullable=false, unique=true)
private String nickname;
#Column(nullable=false)
private Integer uid;
#Column(nullable=false)
private String backendAccessToken;
#Column
private String name;
#Column
#JsonIgnore
private String email;
#Column
private String location;
#Column
private String company;
#Column
private String avatar;
#Column
#JsonIgnore
private String accessToken;
#CreationTimestamp
private Date memberSince;
#ManyToMany(targetEntity=Room.class, cascade={ CascadeType.PERSIST, CascadeType.MERGE })
#JoinTable(name="room_users",
joinColumns={ #JoinColumn(name="user_id") },
inverseJoinColumns={ #JoinColumn(name="room_id") })
private List<Room> rooms = new ArrayList<>();
Room.java
#Entity
#Table(name="rooms", indexes = {
#Index(unique=true, columnList="uid"),
#Index(columnList="uid"),
#Index(columnList="fullName")
})
public class Room extends BasePersistable {
private static final long serialVersionUID = 1L;
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
#Column(nullable=false)
private Integer uid;
#Column(nullable=false)
private String name;
#Column(nullable=true)
private String fullName;
#Column(nullable=false)
#Lob
private String description;
#Column(nullable=true)
private String homepage;
#Column(nullable=false)
private String owner;
#ManyToOne
private Organization organization;
#OneToMany(mappedBy="room")
#JsonIgnore
private List<Message> messages = new ArrayList<>();
#ManyToMany(mappedBy="rooms", targetEntity=User.class)
#JsonIgnore
private List<User> users = new ArrayList<>();
#Column(name="private")
private Boolean _private = false;
And when I try to create the schema, I'm seeing this error:
A Foreign key refering com.models.Room from com.models.User has the wrong number of column. should be 2
I did some research, tried to use JoinColumns annotation on User and didn't worked.
EDIT
I found the error: the class BasePersistable already defined the id. So I removed the id from Room and it worked. Thanks for the tip Mateusz Korwel and kakashihatake
Ok so I have an Entity School.
#Entity
public class School implements Serializable
{
private static final long serialVersionUID = -854333301529125138L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long ID;
private String Type;
private String Name;
private String City;
private String Country;
#OneToOne(cascade = CascadeType.PERSIST,fetch=FetchType.LAZY)
private Info information;
#OneToMany(cascade = CascadeType.PERSIST, mappedBy="school",fetch=FetchType.LAZY)
private List<Contact> Contacts;
#OneToMany(cascade = CascadeType.PERSIST, mappedBy="school",fetch=FetchType.LAZY)
private List<Student> students= new ArrayList<Student>();
// more fields and getters and setters.
The Student Class contains lots of student information, and the student transcripts and is as follows
#Entity
public class Student implements Serializable
{
private static final long serialVersionUID = 5426530769458891752L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Key ID;
#ManyToOne
private School school;
private long SID;
private final long TSTAMP;
private String FName;
private String LName;
private String Email;
private String SchoolName;
#OneToOne(cascade = CascadeType.ALL,fetch=FetchType.LAZY)
private StudentInfo studentInf = new StudentInfo ();
#OneToOne(cascade = CascadeType.ALL,fetch=FetchType.LAZY)
private Transcript transcript;
// more fields and getters and setters.
the Transcript Class in the Student Class is as follows
#Entity
public class Transcript
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Key ID;
#OneToOne(cascade = CascadeType.ALL, mappedBy="transcript",fetch=FetchType.LAZY)
private Student student;
#Embedded
private Course1 c1;
#Embedded
private Course2 c2;
#Embedded
private Course3 c3;
//... ect
public Transcript()
{
this.c1= new Course1();
this.c2= new Course2();
this.c3= new Course3();
// ... ect
}
// more fields and getters and setters.
and finally here is a sample course class
#Embeddable
public class Course1 implements Serializable
{
/**
*
*/
private static final long serialVersionUID = -7643055124732162110L;
private final String CourseTitle = "Course 1 Title";
private boolean MileStone1 = false;
private boolean MileStone2 = false;
// ... ect ... getters and setters
}
All the classes Enhance without a problem and the server runs, but as soon as a Student Instance is created, it results in a total catastrophe in GAE dev server and I have tried alot of possible options with the same error message:
"java.lang.IllegalArgumentException: org.datanucleus.exceptions.NucleusUserException: You have a field db.Entity.student.Student.transcript that has type db.Entity.Courses.Transcript but this type has no known metadata. Your mapping is incorrect"
I would very very much appreciate an explanation on why this is happening and how to fix it while keeping the logical relations