I found here a good article about designing the many-to-many schema with JPA.
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "student_subject", joinColumns = #JoinColumn(name = "student_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "subject_id", referencedColumnName = "id"))
private Set<Subject> subjects;
My question is, can I map a start schema, for example on JoinColumn I want to add multiple tables. It is possible?
Related
so until now I have used a remote server and database and JPA has always created those tables:
but now I have to do something in a local PostgreSQL database and JPA creates only the Entities:
I run the same code. The only thing I have changed is the persistance unit in the Entitimanagerfactory.
Do you guys have any idea why this happens?
Also... I am not posting any code since I don't know where the issue might be and I don't want to post my entire program.
Edit:
#ManyToMany(targetEntity = Question.class, cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
#JoinTable(name = "test",
joinColumns = #JoinColumn(name = "gameId", referencedColumnName = "gameId"),
inverseJoinColumns = #JoinColumn(name = "questionId", referencedColumnName = "questionId"),
uniqueConstraints = #UniqueConstraint(columnNames = {"questionId", "gameId"})
)
private List<Question> questions = new ArrayList<>();
#ManyToMany(targetEntity = Game.class, cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
#JoinTable( name = "test",
joinColumns = #JoinColumn(name = "questionId", referencedColumnName = "questionId"),
inverseJoinColumns = #JoinColumn(name = "gameId", referencedColumnName = "gameId"),
uniqueConstraints = #UniqueConstraint(columnNames = {"questionId", "gameId"})
)
private List<Game> game = new ArrayList<>();
My code is as below. I am using the spring boot with jpa and postgresql database
I need user friendly name as foreign key.
#Entity
#Table(name="course_table")
public class Course extends BaseAuditingEntity {
#ManyToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER)
#JoinTable(name = "course_program_table", joinColumns = #JoinColumn(name = "course_id", referencedColumnName = "course_id", foreignKey = #ForeignKey(name = "fk_program_id")), inverseJoinColumns = #JoinColumn(name = "program_id", referencedColumnName = "program_id", foreignKey = #ForeignKey(name = "fk_course_id")))
private List programs;
}
I have given the name of foreign key using the #ForeignKey annotation but when I see db it is showing the randomly created foreignkey name.
CREATE TABLE course_program_table
(
course_id integer NOT NULL,
program_id integer NOT NULL,
CONSTRAINT fk_28c95hl4nqclyvyxuduei5nbf FOREIGN KEY (program_id)
REFERENCES public.program_table (program_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT fk_5sainywquv8yyu24pjk3jptn7 FOREIGN KEY (course_id)
REFERENCES public.course_table (course_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
I need foreign key as mentioned in the annotation like fk_program_id and fk_course_id.
Thanks in advance.
With a join table this is how you should specify it
#ManyToMany
#JoinTable(name = "course_program_table",
joinColumns = #JoinColumn(name = "course_id", ...)
foreignKey = #ForeignKey(name = "fk_program_id"),
inverseJoinColumns = #JoinColumn(name = "program_id", ...)
inverseForeignKey = #ForeignKey(name = "fk_course_id"))
private List programs;
This is how I do it with the JPA provider I use (not Hibernate), and that is why the #JoinTable has the "foreignKey"/"inverseForeignKey" attributes (the FKs are on/owned by the join table).
If that doesn't work then you need to be looking at raising a bug on your chosen JPA provider.
#ManyToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER)
#JoinTable(name = "tten_courseservice_course_program_table", joinColumns = #JoinColumn(name = "course_id", referencedColumnName = "course_id"), inverseJoinColumns = #JoinColumn(name = "program_id", referencedColumnName = "program_id"))
#ForeignKey(name="fk_tten_courseservice_course_table_course_id",inverseName="fk_tten_courseservice_program_table_program_id")
private List<ProgramEntity> programs;``
I have tried this and now I am able to generate foreign key name properly.
Hope it will help other.
My Empresa entity have 2 nested collections mapped that way:
#ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST})
#JoinTable(
name = "bandeiras_aceitas",
joinColumns = {#JoinColumn(name = "empresa_id", nullable = false)},
inverseJoinColumns = {#JoinColumn(name = "bandeira_id", nullable = false)})
private List<BandeiraCartao> bandeirasAceitas;
#OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL},
mappedBy = "empresa")
private List<HorarioAtendimento> horariosAtendimento;
I actually have 12 records on horariosAtendimento and only 1 record inside bandeirasAceitasfor the Empresa I am trying to fetch. But when I use my find method there are 12 records inside 'bandeirasAceitas', the problem is that the sql generated by jpa(hibernate) is duplicating the records like (number of records on horariosAtendimento* number of records on bandeirasAceitas). How can I solve this?
I have this relationship in my database:
And I want to be able to create an order, that contains more products (as well more instances of the same product). Nevertheless I am able to have just one row in the order_has_product table for every single order_id. Moreover, I tried to load the data via lazyloading, but it won't work and it makes the whole app to run really slowly. Here are definitions of the relationship in my entities:
OrderEntity:
#ManyToMany(fetch = FetchType.LAZY)
#Cascade({org.hibernate.annotations.CascadeType.ALL})
#JoinTable(name = "order_has_product",
joinColumns = {#JoinColumn(name = "order_id", nullable = false, updatable = false)},
inverseJoinColumns = {#JoinColumn(name = "product_id", nullable = false, updatable = false)})
private List<ProductEntity> products;
ProductEntity:
#ManyToMany(fetch = FetchType.EAGER, mappedBy = "products")
private List<OrderEntity> orders;
Any idea how to fix lazyloading and to make it possible to have more products in order?
I have ManyToMany mapping like this:
#XmlTransient
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name = "users_clients",
joinColumns = {#JoinColumn(name = "user_id")},
inverseJoinColumns = #JoinColumn(name = "client_id"))
public List<Client> getClients() {
return clients;
}
And other side:
#ManyToMany(mappedBy = "clients")
private List<User> users = new ArrayList<User>();
So as you can see I have JoinColumn name = user_id and client_id but hibernate mapps this columns with names userS_id and clientS_id as their tables names. Why that happening? Any suggestions?
Try specifying the column name in your #JoinColumn annotation. Also you were missing braces around the inverseJoinColumns
#JoinTable(name = "users_clients",
joinColumns = {
#JoinColumn(name = "user_id", referencedColumnName="user_id")},
inverseJoinColumns = {
#JoinColumn(name = "client_id", referencedColumnName="client_id")})