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
Related
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.
With the query Select c from Card c join User u on c.userId=u.userId where u.username=':u', I am trying to grab a list of Cards for the User based on the username available in User the table. However, I am running into the antlr.SemanticException: could not resolve property: userId of: com.abc.SheridanSportsWAR.entity.Card exception when I run it. How do I reference the UserId column in my Card entity?
Card.java
#Entity
public class Card {
#Id
#Column(name="CardId")
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer cardId;
#Column(name="CardNumber")
private String cardNumber;
#Column(name="CardType")
private String cardType;
#Column(name="ExpiryMonth")
private String expiryMonth;
#Column(name="ExpiryYear")
private String expiryYear;
#Column(name="CardHolder")
private String cardHolder;
#ManyToOne(cascade = {CascadeType.MERGE, CascadeType.DETACH, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinColumn(name = "UserId")
private User userJ;
#OneToMany(mappedBy = "cardJ")
private List<Purchase> purchases;
User.java
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="UserId")
private Integer userId;
#Column(name="FirstName")
private String firstName;
#Column(name="LastName")
private String lastName;
#Column(name="Email")
private String email;
#Column(name="Username")
private String username;
#Column(name="Password")
private String password;
#Column(name="RoleName")
private String roleName;
#OneToMany(mappedBy="userJ", cascade= CascadeType.ALL)
private List<Card> cards;
The error message is pretty clear. There is no field userId in your Card entity. Create one like that:
#Column(name = "UserId", insertable=false, updatable=false)
private Integer userId;
AFAIK, the problem seems to be that there's no userId column in the card table.
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 want to create a many to many relation in my application but it doesen't work.
My first entity:
#Entity
#Table(name = "Person")
public class Person implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Version
private Long version;
private String firstName;
private String lastName;
private String location;
private String email;
private String status;
private String role;
private LocalDateTime createdOn;
private LocalDateTime modifiedOn;
#ManyToMany(mappedBy = "persons")
private Set<Team> teams = new HashSet<Team>();
My second entity:
#Entity
#Table(name = "Team")
public class Team {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Version
private Long version;
private String name;
private String description;
private String city;
private Integer headcount;
private LocalDateTime createdOn;
private LocalDateTime modifiedOn;
#ManyToMany(cascade = CascadeType.MERGE)
#JoinTable(name = "persons_teams",
joinColumns = #JoinColumn(name = "teamId"),
inverseJoinColumns = #JoinColumn(name = "personId"))
private Set<Person> people = new HashSet<>();
I don't know what is wrong but the program doesn't compile.
Please help.
In Person class you have indicated the name of field to be mapped in Team by using name "persons" but the actual field name in Team class is "people".
I have a simple object which I want save in DB. But for time it was necessary to change someone parameters. I drop my old table but when I turn on my program - Hibernate still create DB with old columns.
For example:
My old class looked like this :
#Entity
#Table(name = "Tests")
public class Test {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String description;
private boolean isFree;
private int status;
private String author;
private String section;
#OneToMany(mappedBy = "qTest", fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
private List<Question> questions;
private String commentToAdmin;
...
and geters-seters
}
In table I have column "status" like INT.
But then I change this class parameter to String. Now my class looks like this:
#Entity
#Table(name = "Tests")
public class Test {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String description;
private boolean isFree;
#Column(name = "statusT")
private String status;
private String author;
private String section;
#OneToMany(mappedBy = "qTest", fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
private List<Question> questions;
private String commentToAdmin;
And geters-setters
}
But after drop old table and restart my application column "status" still "INT" and his name "status" (not "statust").
Please help me understand why it's happening