How to set schema location for #ManyToMany Entity Collection with JPA - java

I want to create 2 tables in my PostgreSQL database while using the Spring-boot JPA.
#Entity
#Table(schema = "test")
#Data
#NoArgsConstructor
#AllArgsConstructor
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
And my User class
#Entity
#Table(schema = "test")
#Data
#NoArgsConstructor
#AllArgsConstructor
public class User {
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String group_id;
private String email;
#ManyToMany(fetch = FetchType.EAGER)
private Collection<Role> roles = new ArrayList<>();
}
The 2 tables above are created in test schema but the user_roles is trying to be created without any schema selected and I get the error
Caused by: org.postgresql.util.PSQLException: ERROR: no schema has been selected to create in
So my question is: How to assign the schema to the user_roles table that JPA is trying to create

Related

Column doesn`t exist

Try to learn hibernate + jpa, don`t know what to do with this. Error when getting by id.
JDBC exception executing SQL [select u1_0.id,u1_0.email,u1_0.login,u1_0.password,r1_0.id,r1_0.name from user u1_0 left join role r1_0 on r1_0.id=u1_0.role_id where u1_0.id=?]
Caused by: org.postgresql.util.PSQLException: ERROR: column u1_0.role_id doesn`t exist
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(nullable = false, unique = true)
private String login;
#Column(nullable = false)
private String password;
#Column(nullable = false, unique = true)
private String email;
#ManyToOne
#JoinColumn(name = "role_id")
private UserRole role;
}
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
#Table(name = "role")
public class UserRole {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(nullable = false)
private String name;
}
enter image description here
Tried to debug but no results

Extra association table is created in spring boot

I'm currently working on developing a recipe application and I'm having trouble with DB table generation.
Here are the Entity files I'm using:
// Recipe.java
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "recipes")
public class Recipe {
#Id
#GeneratedValue
private int id;
private String name;
private String description;
private String instruction;
#ManyToOne
private User user;
#OneToMany(cascade=CascadeType.ALL)
private List<RecipeIngredient> ingredients = new ArrayList<>();
}
// Ingredient.java
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "ingredients")
public class Ingredient {
#Id
#GeneratedValue
private int id;
private String name;
}
// RecipeIngredient.java
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
public class RecipeIngredient {
#Id
#GeneratedValue
private int id;
#ManyToOne
private Ingredient ingredient;
private String amount;
}
Spring Boot Automatically creates tables for me but I just wanna have one table for RecipeIngredient, but it creates two tables for them.
It works perfectly fine but the thing I want is just how to make these two tables into one or make spring boot not generate one of them.
If you want recipe_ingedients table only delete recipeIngredient Entity Class and if you want to keep recipe_ingredient table remove this:
#OneToMany(cascade=CascadeType.ALL)
private List<RecipeIngredient> ingredients = new ArrayList<>();

Hibernate 6 perfroms update query after select query

I wrote a simple entity named "User" and another one called "Company". User entity has company inside with #ManyToOne(fetch = LAZY) mapping. When I create the session object and call get() method Hibernate executes select query and after it update, why?
User entity:
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
#ToString
#Builder
#Entity
#Table(name = "users")
public class User2 {
#Id
#GeneratedValue(strategy = IDENTITY)
private Long id;
#Column(unique = true)
private String username;
#Embedded
#EqualsAndHashCode.Exclude
private PersonalInfo personalInfo;
#Enumerated(STRING)
#EqualsAndHashCode.Exclude
private Role role;
#Type(JsonType.class)
#EqualsAndHashCode.Exclude
private String info;
#ManyToOne(fetch = LAZY)
#JoinColumn(name = "company_id")
#EqualsAndHashCode.Exclude
#ToString.Exclude
private Company company;
}
Company entity:
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode
#ToString
#Builder
#Entity
public class Company {
#Id
#GeneratedValue(strategy = IDENTITY)
private Long id;
private String name;
}
Main:
public class HibernateEntityMappingRunner {
public static void main(String[] args) {
try (SessionFactory sessionFactory = buildSessionFactory();
Session session = sessionFactory.openSession()
) {
session.beginTransaction();
User2 user2 = session.get(User2.class, 2);
session.getTransaction().commit();
}
}
}
Hibernate console log:
Hibernate:
select
u1_0.id,
u1_0.company_id,
u1_0.info,
u1_0.birth_date,
u1_0.firstname,
u1_0.lastname,
u1_0.role,
u1_0.username
from
users u1_0
where
u1_0.id=?
Hibernate:
update
users
set
company_id=?,
info=?,
birth_date=?,
firstname=?,
lastname=?,
role=?,
username=?
where
id=?
See https://hibernate.org/community/contribute/intellij-idea/#debugging for details. The problem is that some of your toString() implementations (which the IntelliJ debugger invokes) access state of uninitialized entity/collection proxies, which will cause lazy initialization and hence a select query. If you have pending flushes (insert/update/delete) which affect one of the tables that are about to be selected from, Hibernate forcefully executes pending flushes.
By changing your toString() implementations or changing how IntelliJ shows objects in the debugger, you can avoid this.

ManyToOne realtionship in Java Spring Boot

Well, I have a class Feeding.java and a class User.java
One Feeding should have one User but a User can have many Feedings.
This is my Feeding.java class:
#Getter
#Setter
#EqualsAndHashCode
#NoArgsConstructor
#Entity
#Table(name = "tblFeeding")
public class Feeding {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer idFeeding;
private LocalDateTime dateFeeding;
private double amountFeeding;
private String foodFeeding;
#ManyToOne
#JoinColumn(name = "id_user")
private User user;
}
This is my User.java class:
#Entity
#Getter
#Setter
#Table(name = "tbl_User")
public class User implements UserDetails {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer idUser;
private String nameUser;
private String email;
private String passwordUser;
The problem at the moment is that I can save feeding object with an userId that doesn't exist and this shouldn't be possible.
A foreign constraint is missing. If you have created the table with Hibernate ORM it shouldn't happen but if you've created the table in a different way, it's possible that the foreign constraint has not been created.
You would need to run a SQL query similar to this one:
ALTER TABLE Feeding
ADD CONSTRAINT id_user_fk
FOREIGN KEY (id_user) REFERENCES User;
Note that the query might be different, you need to check the exact query for your database.
This query is from the Hibernate ORM documentation example for many-to-one associations.

Multiply ID mapping throw BaseEntity

I'm mapping classes via Hibernate and I need to map multiple ID for Relationship.
All ID's extend from BaseEntity. How can I implement multiple ID mapping for Relationship which contains Foreign Key for User in DataBase ?
Basicly fields userIdOne and userIdTwo in Relationship has to contain user's id which send request.
User extend own ID from BaseEntity.
Each time I run it - get en error:
This class [class com.mylov.springsocialnetwork.model.Relationship]
does not define an IdClass
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#MappedSuperclass
#EqualsAndHashCode
public class BaseEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
#Builder
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode(exclude = {"posts"}, callSuper = false)
#Entity
public class User extends BaseEntity {
private String userName;
private String realName;
private String email;
private String phoneNumber;
private LocalDate birthDate;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userPosted")
private Set<Post> posts = new HashSet<>();
private String password;
public User(Long id, String userName, String realName, String email, String phoneNumber, LocalDate birthDate,
Set<Post> posts, String password) {
super(id);
this.userName = userName;
this.realName = realName;
this.email = email;
this.phoneNumber = phoneNumber;
this.birthDate = birthDate;
this.posts = posts;
this.password = password;
}
}
#Builder
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Entity
public class Relationship implements Serializable {
//#Id not working
private Long userIdFrom;
//#Id
private Long userIdTo;
#Enumerated(value = EnumType.STRING)
private RelationshipStatus status;
private LocalDate friendsRequestDate;
}
It appears that you are looking to establish a Relationship between two different users. This would mean that each Relationship is an object/entity of its own and should have its very own #Id (unrelated to user IDs).
The linkage to each User that form part of this Relationship should be mapped as foreign keys instead (probably #ManyToOne and a #JoinColumn).
For example:
#Entity
public class Relationship implements Serializable {
#Id
private Long relationshipId;
#ManyToOne(...)
#ForeignKey(name="FK_USER_ONE") //for generation only, it isn't strictly required
#JoinColumn(name="from")
private Long userIdFrom;
#ManyToOne(...)
#ForeignKey(name="FK_USER_TWO") //for generation only, it isn't strictly required
#JoinColumn(name="to")
private Long userIdTo;
#Enumerated(value = EnumType.STRING)
private RelationshipStatus status;
private LocalDate friendsRequestDate;
}
Edit:
It isn't required to specify the #ForeignKey annotations. They will be used if the database tables are generated automatically (ok for testing, but usually not something you'll want in production) and will create the FOREIGN KEY constraint on the table accordingly, but JPA mapping will work fine without it, because it takes the relationships from your defined model, not from the database itself.

Categories