Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: jpa+springboot - spring-boot

model classes
#Entity
#Table(name="RequisitionRequest")
public class Requisition {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String requestedPerson;
private String contactDetails;
private String appliedDate;
private String branch;
private String department;
private String status;
#OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER,mappedBy = "RequisitionRequest")
private List<Nationality> nationality;
//getters and setters
}
class Nationality
#Entity
#Table(name="nationality")
public class Nationality {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String nationality;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "nationality_id", nullable = false)
private Requisition requisition;
//getters and setters
}
repository classes
#Repository
public interface NationalityRepository extends JpaRepository<Nationality,Long>{
}
#Repository
public interface RequisitionRepository extends JpaRepository<Requisition,Long> {
}
service class
#Service
public class RequisitionServiceImpl implements RequisitionService {
#Autowired
RequisitionRepository requisitionRepository;
#Override
public void save(Requisition requisition) {
requisitionRepository.save(requisition);
}
}
controller class
#RestController
public class RequisitionController {
#Autowired
RequisitionService requisitionService;
#Autowired
RequisitionRepository requisitionRepository;
#PostMapping("/requisition/")
#CacheEvict(value = "requisitions", allEntries=true)
public ResponseEntity<Requisition> addRequisition(#RequestBody Requisition requisition) {
System.out.print(requisition);
Requisition requisitionR = new Requisition();
Requisition response = new Requisition();
requisitionR.setBranch(requisition.getBranch());
requisitionR.setDepartment(requisition.getDepartment());
requisitionR.setExpectedDateofJoin(requisition.getExpectedDateofJoin());
//requisitionR.setNationality(requisition.getNationality());
requisitionRepository.save(requisitionR);
return new ResponseEntity<Requisition>(response, HttpStatus.OK);
}
i am learning spring boot,just writing sample program to learn spring boot+jpa+one-to-many relation.when execute this above code getting error like
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: officekitRecruitment.model.Nationality.RequisitionRequest in officekitRecruitment.model.Requisition.nationality
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:769) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:719) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1655) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1623) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
I tried the solutions already mentionned in this site but it doesn't work for me.
Can anybody helps me to resolve this issue

You should refer to the name of the Field in mapped entity on your MappedBy parameter.
Like that
mappedBy = "requisition"

Related

How Can I mapping DTOs using mapstruct?

I am tring to mapping entity datas to DTOs using mapstruct.
And with these sources, I could map id,title datas.
But the problem is.... I can not map userName using these sources.
How can I resolve this problem??
#Entity // DB와의 연결을 위하여
#Data // getter setter
public class Board {
#Id // id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Size(min=2, max=30)
private String title;
#Length(min=20)
#Lob
#Column(columnDefinition="TEXT", nullable = false)
private String content;
#ManyToOne
#JoinColumn(name="userId", referencedColumnName = "id")
private User user;
}
#Builder
#AllArgsConstructor
#Data
public class BoardListDto {
private Long id;
private String title;
private String userName;
}
#Mapper(componentModel = "spring")
public interface BoardListMapper extends EntityMapper<BoardListDto, Board> {
#Override
#Mapping(target = "userName", source = "user.name.value")
List<BoardListDto> toDtos(List<Board> board);
}
public interface EntityMapper <D, E> {
E toEntity(D dto);
D toDto(E entity);
// Entity업데이트 시 null이 아닌 값만 업데이트 하도록 함.
#BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void updateFromDto(D dto, #MappingTarget E entity);
List<D> toDtos(List<E> entity);
}
no need to implement toDtos method for this. This code should be enough and Mapstruct will handle the rest alone.
#Mapper(componentModel = "spring")
public interface BoardListMapper extends EntityMapper<BoardListDto, Board> {
#Override
#Mapping(target = "userName", source = "user.name")
BoardListDto toDto(Board board);
}

nested exception is org.hibernate.MappingException: Could not determine type for: Com.test.model.Client, at table: ComptePaiement

I'm using Hibernate in my spring project. But It doesn't work for One-To-One relationships. It gives me the below error.
Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: com.example.TransfertNational.model.Client, at table: ComptePaiement, for columns: [org.hibernate.mapping.Column(client)]
I have ran some searches in the internet, but it doesn't work for me.
the Client Entity :
#Data #Entity
#AllArgsConstructor #NoArgsConstructor #ToString
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String typeTransfert;
private String typePiece;
private String cin;
private String sexe;
private String prenom;
private String typePieceIdentite;
private String paysEmission;
private String numPI;
private String validitePI;
private String dateNaissance;
private String profession;
private String nationalite;
private String paysAdresse;
private String adresseLegale;
private String ville;
private String gsm;
private String email;
#OneToMany(fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private Set<Beneficiaire> beneficiares;
#OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private ComptePaiement comptePaiement;
}
the ComptePaiement Entity :
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
#ToString
public class ComptePaiement {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String solde;
private String rip;
private Client client;
}
Answer from comments:
You are probably missing #JoinColumn on Client or ComptePaiement and mappedBy in #OneToOne annotation, depending which will hold reference id in database.

MultipleBagFetchException whent I try load entity with 2 collections use JPA EntityGraph

I have user entity:
#ToString
#Data
#Entity
#Table(name = "users")
#NamedEntityGraph(name = "UserWithItems",
attributeNodes = {
#NamedAttributeNode("items"),
#NamedAttributeNode("roles")
})
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Item> items;
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Role> roles;
}
item:
#ToString(exclude = "user")
#Data
#Entity
#Table(name = "items")
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#ManyToOne
#JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)
private User user;
}
role:
#ToString
#Data
#Entity
#Table(name = "roles")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#ManyToOne
#JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)
private User user;
}
I want load user with items and roles. I use #NamedEntityGraph. It is my repository:
#EntityGraph(value = "UserWithItems", type = EntityGraph.EntityGraphType.LOAD)
#Query("select u from User u where u.id = ?1 and u.name =?2")
User getOneById(Long id, String name);
But I get an error:
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [com.example.egerload.entity.User.roles, com.example.egerload.entity.User.items]
at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:75) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.loader.hql.QueryLoader.<init>(QueryLoader.java:108) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:212) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:143) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:119) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:85) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.query.internal.AbstractProducedQuery.makeQueryParametersForExecution(AbstractProducedQuery.java:1350) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1539) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1505) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
... 41 common frames omitted
You can split your "UserWithItems" #NamedEntityGraph into two #NamedEntityGraphs, resulting in two queries, as described in Hibernate throws MultipleBagFetchException - cannot simultaneously fetch multiple bags - answer of Vlad Mihalcea.
User
#ToString
#Data
#Entity
#Table(name = "users")
#NamedEntityGraphs(
{
#NamedEntityGraph(
name = "UserWithItems",
attributeNodes = {
#NamedAttributeNode("items")
}
),
#NamedEntityGraph(
name = "UserWithRoles",
attributeNodes = {
#NamedAttributeNode("roles")
}
),
}
)
public class User {
...
}
I assume you have a repository class. For example with extends JpaRepository. Use each NamedEntityGraph on an extra method. (I have omitted the name condition and #Query("..."). The id condition should be sufficient, since it is the user's identifier. #Query("...") is not needed.)
UserRepository
public interface UserRepository extends JpaRepository<User, Long> {
#EntityGraph(value = "UserWithItems", type = EntityGraph.EntityGraphType.LOAD)
Optional<User> getOneWithItemsById(Long id);
#EntityGraph(value = "UserWithRoles", type = EntityGraph.EntityGraphType.LOAD)
Optional<User> getOneWithRolesById(Long id);
....
}
Finally, you can call both methods in a service.
UserService
public interface UserService {
Optional<User> readById(Long id);
}
UserServiceImpl
#Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
#Override
#Transactional
public Optional<User> readById(Long id) {
// Load user with items into persistence contex
userRepository.getOneWithItemsById(id);
// Load user with roles into persistence context
// (There is only one user instance by id within the persistence context)
return userRepository.getOneWithRolesById(id);
}
}

Invoking other service URL using feign client gives error in postman

I have two services. One is UserDetails service and another is Post service. In userdetails I have a controller in which I am filtering the details of user using areacode.
#GetMapping("/userdetailsbyareacode/{areacode}")
public ResponseEntity<List<UserDetails>> getUserByAreacode(#PathVariable(value="areacode") Long areacode){
List<UserDetails> user=userdetailsService.getuserByAreacode(areacode);
if(user==null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok().body(user);
}
now in post service I am calling this controller method using feign client and filter the post details based on areacode which is in the userdetails. Bothe userdetails and post service have u_id common.
Based on u_id I am filtering the post details from my repository.
public interface PostRepository extends JpaRepository<Posts,Long>
{
#Transactional
#Query(nativeQuery=true,value="SELECT * FROM POSTS WHERE U_ID=:u_id")
List<Posts> findPostsByU_id(#Param("u_id") Long u_id);
}
And here is my post DAO-
public List<Posts> findByU_id(Long u_id){
List<Posts> post=new ArrayList<>();
postRepository.findPostsByU_id(u_id).forEach(post::add);
return post;
}
Now this is the post controller method which I am calling in postman, which is using the feign proxy for calling the UserDetails controller method.
#GetMapping("/findpostbyareacode-feign/{areacode}")
public List<Posts> getPostByAreacodeUsingfeign(#PathVariable(value="areacode") Long areacode){
List<UserDetails> usersList=userProxy.getUserByAreacode(areacode);
List<Posts> postList=new ArrayList<>();
List<Posts> totalPost=new ArrayList<>();
for(UserDetails users : usersList) {
totalPost=postService.findByU_id(users.getU_id());
for(Posts posts : totalPost) {
postList.add(posts);
}
}
return postList;
}
When I am hitting the URL in postman, I am getting this error.
"error": "Internal Server Error",
"message": "could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet",
Here is my UserDetails entity class of UserDetails service.
#Entity
#Table(name="user_details")
#Builder
#Data
#Getter #Setter #NoArgsConstructor #AllArgsConstructor
public class UserDetails implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="user_id", unique=true)
private Long user_id;
#Column(name="user_name", length=35, nullable=false)
#Size(min=2,message="Name should have atleast 2 character")
private String user_name;
#Column(name="gender", nullable=false)
private String gender;
#Column(name="dob")
#DateTimeFormat(pattern="yyyy-MM-dd")
private Date dob;
#Column(name="email", length=50, unique=true, nullable=false)
private String email;
#Column(name="phno", length=11, nullable=false)
private String phno;
#Column(name="password", nullable=false)
//#JsonIgnore
private String password;
#Column(name="areacode", length=11)
private Long areacode;
#Column(name="u_Id")
private Long u_id;
}
And here is my post entity of Post service-
#Entity
#Table(name="vob_posts")
#Getter #Setter #NoArgsConstructor #AllArgsConstructor
public class Posts implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="post_id", unique=true)
private Long post_id;
#Column(name="contents")
private String contents;
#Column(name="u_id")
private Long u_id;
}
My both services are registered in eureka.
Cant solve this issue, pls help anyone.
why you are making code complex and How come primary key returns List<Posts>. Try with the below code.
Just make change below in your Entity and Repository.
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="user_id", unique=true)
private Long id;
//private Long userId;
#Column(name="user_name", length=35, nullable=false)
#Size(min=2,message="Name should have atleast 2 character")
private String userName;
public interface PostRepository extends JpaRepository<Posts,Long>
{
}
(or)
public interface PostRepository extends CrudRepository<Posts,Long>
{
//Optional<Posts> posts findByUserId(Long userId);
}
Service Layer :
Approach 1 : Using JPA Repository
Posts posts = repo.getOne(userId);
Approach 2 : Using Crud Repository
Posts posts = repo.findById(userId).get();
//Posts posts = repo.findByUserId(userId).get();

Spring Boot : Error :Cannot call sendError() after the response has been committed

I am getting this error .
Cannot call sendError() after the response has been committed
Can someone help me figure out why?.
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#OneToOne(
fetch = FetchType.LAZY,
cascade = CascadeType.ALL
)
#JoinColumn(name = "details_id")
private Details details;
//Getters and setters left out for brevity
}
#Entity
public class Details {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String description;
private float price;
private float discount;
#OneToOne(mappedBy = "details")
private Product product;
}
#RestController
public class ProductController {
#Autowired
ProductRepository productRepository;
#GetMapping("/getAllProducts")
public Iterable<Product> getAllProducts(){
return productRepository.findAll();
}
}
#RestController
public class DetialsController {
#Autowired
ProductRepository productRepository;
#Autowired
DetailsRepository detailsRepository;
#PostMapping("/details")
public Details addDetails(#RequestBody Details details) {
Product newProduct = new Product();
newProduct.setDetails(details);
productRepository.save(newProduct);
return detailsRepository.save(details);
}
}
I am able to make the POST call to /details; for adding details successfully. But when i make GET call to /getAllProducts, I am getting this error
Cannot call sendError() after the response has been committed
This is an issue with bidirectional relationships, as they hold references to each other, at deserialization, Jackson runs in an infinite loop. My first suggestion would be adding #JsonIgnore to one end of the relation.
#OneToOne(mappedBy = "details")
#JsonIgnore
private Product product;
Afterward, if that solved your issue, you can look over #JsonManagedReference/#JsonBackReference and #JsonIdentityInfo.
You can also look over this link for more insight
You can use this :
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#JsonBackReference(value = "details_id")
#OneToOne(
fetch = FetchType.LAZY,
cascade = CascadeType.ALL
)
#JoinColumn(name = "details_id")
private Details details;
//Getters and setters left out for brevity
}
#Entity
public class Details {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String description;
private float price;
private float discount;
#JsonManagedReference(value = "details")
#OneToOne(mappedBy = "details",,cascade=CascadeType.ALL)
private Product product;
}

Resources