mappedBy reference an unknown target entity property role based - java

1 user ==> many roles
1- role ==> many components
for this I have configured like
userDao.java
#Entity
#Table(name = "User_info")
public class UserDao {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int userId;
#Column(name="username")
private String username;
#Column(name="password")
#JsonIgnore
private String password;
#ManyToMany(cascade=CascadeType.MERGE,fetch = FetchType.EAGER)
#JoinTable(
name="user_role",
joinColumns={#JoinColumn(name="USER_ID", referencedColumnName="userId")},
inverseJoinColumns={#JoinColumn(name="ROLE_ID", referencedColumnName="roleId")})
private List<Role> roles;
Role.java
#Entity
#Table(name = "roles")
public class Role {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private Integer roleId;
#Column(nullable = false, unique = true)
#NotEmpty
private String roleName;
#ManyToMany(mappedBy = "roles")
private List < UserDao > users;
#ManyToMany(cascade=CascadeType.MERGE,fetch = FetchType.EAGER)
#JoinTable(
name="role_component",
joinColumns={#JoinColumn(name="ROLE_ID", referencedColumnName="roleId")},
inverseJoinColumns={#JoinColumn(name="COMP_ID", referencedColumnName="compId")})
private List<Component> components;
component.java
#Entity
#Table(name = "component")
public class Component {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer compId;
#Column(nullable = false, unique = true)
#NotEmpty
private String compName;
#ManyToMany(mappedBy = "component")
private List < Role > roles;
I am getting the following error, Please suggest the mistake
Caused by: org.hibernate.AnnotationException: mappedBy reference an
unknown target entity property:
net.springboot.helloworldapp.bean.Role.component in
net.springboot.helloworldapp.bean.Component.roles at
org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:785)

There is a typo. component should be components.
#ManyToMany(mappedBy = "components") // <- should be components
private List < Role > roles;

Related

foreign key not getting inserted when hibernate one to one mapping is used

I have two entites as follows
user entity
#Entity
#Table(name = "user")
#Getter
#Setter
public class UserEntity{
#Id
#GeneratedValue(strategy = GeneratedType.IDENTITY)
#Column(name = "user_id")
private Long userId;
#Column(name = "user_name")
private String name;
#OneToOne(Cascade=CascadeType.ALL, mappedBy="user")
private UserAddressEntity addressEntity;
}
user address entity
#Entity
#Table(name = "user_address")
#Getter
#Setter
public class UserAddressEntity{
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "user_id")
private Long userId;
#Column(name = "address")
private String address;
#OneToOne
#JoinColumn(name = "user_id", nullable = false, referencedColumnName = "user_id")
private UserEntity user;
}
I am saving user entity as follows in service class
#Service
public class UserService{
#Autowired
private UserRepository userRepository;
public void saveUser(){
UserEntity userEntity=new UserEntity();
UserAddressEntity userAddressEntity=new UserAddressEntity();
//logic here
userEntity.setAddressEntity(userAddressEntity);
userRepository.save(userEntity);
}
}
After saving entity user_id column is not being saved in user_address table. It's value is saved as null.I can't seem to find where the issue is.
EDIT:
I have added following to entities after answer referred in comments but I am getting this error
Infinite recursion (StackOverflowError)
#Entity
#Table(name = "user")
#Getter
#Setter
public class UserEntity{
#Id
#GeneratedValue(strategy = GeneratedType.IDENTITY)
#Column(name = "user_id")
private Long userId;
#Column(name = "user_name")
private String name;
#OneToOne(Cascade=CascadeType.ALL, mappedBy="user")
private UserAddressEntity addressEntity;
//added this
public void setAddressEntity(UserAddressEntity addressEntity){
if (!addressEntity.equals(this.addressEntity)){
this.addressEntity=addressEntity;
addressEntity.setUser(this);
}
}
#Entity
#Table(name = "user_address")
#Getter
#Setter
public class UserAddressEntity{
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "user_id")
private Long userId;
#Column(name = "address")
private String address;
#OneToOne
#JoinColumn(name = "user_id", nullable = false, referencedColumnName = "user_id")
private UserEntity user;
//added this
public void setUser(UserEntity user){
if (!user.equals(this.user){
this.user=user;
}
}
}
You need to set the relationship correctly in UserService.saveUser():
userEntity.setAddressEntity(userAddressEntity);
userAddressEntity.setUser(userEntity);
Also, use regular getters/setters, no need to add logic there.
The recommended/best way to map a #OneToOne is to use #MapsId. With that approach, you don’t need at all a bidirectional association.
I would advise you to take look at link below, there you have answer to your question with example how to save and map between objects.
https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/

How to extend a class in Spring Boot without changing the MySQL schema?

For example, I have the User class, with looks like the next:
#Entity
#Table(name = "users")
public class User{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#NotBlank
#Size(max = 40)
#Column(name = "name")
private String name;
#NotBlank
#Size(max = 15)
#Column(name = "username")
private String username;
#NaturalId
#NotBlank
#Size(max = 40)
#Email
#Column(name = "email")
private String email;
#NotBlank
#Size(max = 100)
#Column(name = "password")
private String password;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "user_roles",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
//Constructor
//Getters and Setters
And I have the Client class:
#Entity
#Table(name = "cliente")
public class Cliente {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "empresa")
private String empresa;
#Column(name = "telefono")
private Integer telefono;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(unique = true)
private Licencia licencia;
#OneToMany(cascade = {
CascadeType.PERSIST,
CascadeType.REMOVE
} ,fetch = FetchType.EAGER)
#JoinTable(name = "user_cliente",
joinColumns = #JoinColumn(name = "cliente_id"),
inverseJoinColumns = #JoinColumn(name = "user_id"))
private Set<User> users = new HashSet<>();
public Cliente(String empresa, Integer telefono) {
this.empresa = empresa;
this.telefono = telefono;
}
//Constructor
//Getters and Setters
Now, what I want to do is the Client class to extends the User class, so I can add a Client with name, username, email, etc. But I want two separate tables in MySQL, one for the users and its attributes, and other for clients only with the information of client, like the telephone or company. The problem is when I extends the User class in Client class, the MySQL databases updates and create the fields of telephone, company, etc. in the User table. How can I avoid this?
Use #MappedSuperclass:
#MappedSuperclass
public class BaseEntity {
// here you can add common fields for your entities
}
and then extend from it:
#Entity
public class User extends BaseEntity {
// user specific fields goes here
}
and Client:
#Entity
#Table(name = "cliente")
public class Cliente extends BaseEntity {
// client specific fields here
}
For more info read How to inherit properties from a base class entity using #MappedSuperclass with JPA and Hibernate

How should I get related entity?

I want to understand how to work with related entities in Hibernate.
There are two related entities:
#Entity
#Table(name = "usr")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String username;
#Column(nullable = false)
private String password;
#Column(nullable = false)
private String email;
private boolean active;
#Enumerated(EnumType.STRING)
private Role role;
#OneToMany(fetch = FetchType.LAZY,
mappedBy = "responsibleUser", cascade = CascadeType.ALL)
private List<GrowBox> growBoxes;
//def-constructor , getters, setters
}
and
#Entity
#Table(name = "growBoxes")
public class GrowBox {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
#Column(nullable = false)
private Integer length;
#Column(nullable = false)
private Integer width;
#Column(nullable = false)
private Integer height;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "responsibleGrowBox", cascade = CascadeType.ALL)
private List<Plant> plants;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "activeGrowBox", cascade = CascadeType.ALL)
private List<Sensor> sensors;
#ManyToOne
#JoinColumn(name = "user_id")
private User responsibleUser;
//def-constructor , getters, setters
}
I have registered mapping using annotations. Hope it is correct. And I want to find box by user Id, but don't know how HQL query should be written. 'Cause there is no "user_id" field in my Box Class. Instead there is "User responsibleUser" field. And smth like this won't work(should not)
#Autowired
SessionFactory sessionFactory;
#Override
public List<GrowBox> findByUser(Long userId) {
Session session = sessionFactory.openSession();
String hqlQuery = "from GrowBox where user_id =: userId";
Query query = session.createQuery(hqlQuery);
List growBoxes = query.getResultList();
session.flush();
session.close();
return growBoxes;
}
A HQL query would be
String hqlQuery = "from GrowBox gb where gb.responsibleUser.id =: userId";

Identifier Generation Exception

I have some problems with identifier generation. I use MySQL database. So, I have two entities:
#Entity
#Table(name = "users", catalog = "test1")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id", unique=true, nullable=false, updatable=false)
private Long id;
private String username;
private String password;
private boolean enabled;
#JsonBackReference
private Set<UserRole> userRole = new HashSet<UserRole>(0);
#OneToOne(cascade={CascadeType.ALL}, fetch = FetchType.LAZY, targetEntity = Utilisateur.class)
#JoinColumn(name="userUtilisateur")
#JsonManagedReference
private Utilisateur userUtilisateur;
/*.. getters and setters..*/ }
and
#Entity
#Table(name="utilisateur")
public class Utilisateur {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "firstName")
private String firstName;
#Column(name = "lastName")
private String lastName;
private String fullName;
#Column(name = "age")
private int age;
#OneToMany(mappedBy="utilisateur", targetEntity = Ticket.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JsonBackReference
private Set<Ticket> tickets = new HashSet<Ticket>(0);
#OneToMany(mappedBy="utilisateur", targetEntity=UserAssignProject.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JsonBackReference
private Set<UserAssignProject> userAssignProjects = new HashSet<UserAssignProject>(0);
#OneToMany(mappedBy="utilisateur", targetEntity=Message.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JsonBackReference
private Set<Message> messages = new HashSet<Message>(0);
/*.. getters and setters..*/ }
I have this method in UserDaoImpl:
public void save(User user) {
Utilisateur utilisateur = new Utilisateur();
user.setId(user.getId());
user.setUsername(user.getUsername());
user.setPassword(user.getPassword());
user.setEnabled(true);
user.setUserUtilisateur(utilisateur);
getCurrentSession().save(user);
}
Results:
Exception here
I've tried to use sequence, GenerationType.AUTO..., but it's not working.
Any solutions?
Thanks for your attention!

How corectly select entity with ManyToMany realationship in Hibernate jpa

I have two tables(entities):
#Entity
#Table(name = "users")
#NamedQuery(name = "User.getAll", query = "SELECT c from User c")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#NotNull
#Column(name = "LOGIN")
private String login;
#Column(name = "PASSWORD", length = 64)
private String password;
#Column(name = "SALT", length = 80)
private String salt;
#ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
private Set<Role> roles;
#OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Permission> permissions;
And
#Entity
#Table(name = "roles")
#NamedQuery(name = "Role.getAll", query = "SELECT c from Role c")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Column(name = "ROLE_NAME", length = 100)
private String roleName;
#ManyToMany(mappedBy = "roles")
private Set<User> users;
And method for select Users:
#Override
public List<User> getUsersList() {
Criteria criteria = getSession().createCriteria(User.class);
return (List<User>)criteria.list();
}
I have 2 users. First user has 2 roles and second user has 1 role.
But this method return me 3 users. User who has 2 role is dublicate.
Itried criteria.createCriteria("", JoinType.NONE);
but it not helped.
You need to use criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY), check:
criteria-distinct-root-entity-vs-projections-distinct

Categories