: mappedBy reference an unknown target entity property - java

I am working on a simple practice application for using hibernate. It has simple mapping like a manufacturer can have many mobiles. But a mobile can only be manufactured by single manufacturer. Here is what I think the code should be.
package mobileconsumers.entity.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="ms_ref_mobile")
public class MobileDTO {
private Long id;
private String model;
private ManufacturerDTO manufacturerDTO;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="MOBILE_ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="MANUFACTURER_ID")
public ManufacturerDTO getManufacturer() {
return manufacturerDTO;
}
public void setManufacturer(ManufacturerDTO manufacturer) {
this.manufacturerDTO = manufacturer;
}
}
this is the second dto
package mobileconsumers.entity.dto;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="ms_ref_manufacturer")
public class ManufacturerDTO {
private Long id;
private String name;
private Set<MobileDTO> mobileDTOs = new HashSet<>(0);
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="MANUFACTURER_ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name="NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(fetch=FetchType.LAZY,mappedBy="manufacturerDTO")
public Set<MobileDTO> getMobileDTOs() {
return mobileDTOs;
}
public void setMobileDTOs(Set<MobileDTO> mobileDTOs) {
this.mobileDTOs = mobileDTOs;
}
}
When I try to start my server it gives me an error saying..
org.hibernate.AnnotationException: mappedBy reference anunknown target entity property: mobileconsumers.entity.dto.MobileDTO.manufacturerDTO in mobileconsumers.entity.dto.ManufacturerDTO.mobileDTOs
The mapping seems to be fine to me. there must be something really silly that I am missing out. Just needed fresh pair of eyes to look at my code and figure out whats going wrong..

Change mappedBy value, so that it refers the manufacturer property on the #ManyToOne side of the association:
#OneToMany(fetch=FetchType.LAZY,mappedBy="manufacturer")
public Set<MobileDTO> getMobileDTOs() {
return mobileDTOs;
}

Related

Can't save data to a database with DTO

This question is kindly related to a previous one here:
getting null while posting data
I tryed a suggested answer, imported lombok and created a DTO class as follows:
package com.example.dto;
import java.util.HashSet;
import java.util.Set;
import lombok.Data;
#Data
public class TownDTO {
public String name;
public String regionid;
}
Table towns is related to a regions table in db. While I try to save data I am getting a following exception:
not-null property references a null or transient value : com.example.model.Towns.regionid
Here is my model class
package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "towns")
public class Towns {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "name")
private String name;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "regionid", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
private Regions regionid;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Regions getRegionid() {
return regionid;
}
public void setRegionid(Regions regionid) {
this.regionid = regionid;
}
}
And repositories are as follows.
Towns repository
package com.example.repository;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
import com.example.model.Towns;
import com.example.model.Regions;
public interface TownsRepository extends JpaRepository<Towns, Integer> {
List<Towns> findByNameContaining(String name);
Page<Regions> findByregionid(Integer regionid, Pageable pageable);
Optional<Regions> findByregionidAndId(Integer regionId, Integer id);
}
regions repository
package com.example.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.model.Regions;
public interface RegionsRepository extends JpaRepository<Regions, Integer> {
List<Regions> findByNameContaining(String name);
}
And finaly the controller method:
#PostMapping("/add")
public ResponseEntity<TownDTO> createPost(#RequestBody TownDTO townDto) {
// convert DTO to entity
Towns townRequest = modelMapper.map(townDto, Towns.class);
//System.out.println(townDto.regionid);
//System.out.println(townRequest.getName());
Towns town = townsrepository.save(townRequest);
// convert entity to DTO
TownDTO townResponse = modelMapper.map(town, TownDTO.class);
return new ResponseEntity<TownDTO>(townResponse, HttpStatus.CREATED);
}
I am able to print out townDTO.regionid and value is correct 2 in my case. But request is still null. Here is a request from postman
{
"name": "test",
"regionid": "2"
}
What am I missing right now?
Removed #jsonignore and added getters and setters to DTO
package com.example.dto;
import java.util.HashSet;
import java.util.Set;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
#Data
public class TownDTO {
public String name;
public String regionid;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRegionid() {
return regionid;
}
public void setRegionid(String regionid) {
this.regionid = regionid;
}
}
Nothin had change. Error is the same
Your TownDTO contains String regionid whereas your Model class it's Region Object. So moddlemapper can't map.
//DTO
public String regionid;
//Model
private Regions regionid;

How to do the CURD operations on Spring Boot Restful API using Sping Data Jpa OneToMany nested model?

I was trying to make a crud app which has two model objects of type Muscle and Exercise. Basically One Muscle Object can have a list of Exercise objects. I wanted to implement the CRUD operations for the both the model object. For Muscle object it was very straight forward but for the Exercise Object for the put/Update operation I am getting the following error "JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference" . And further more if I try to delete one exercise, somehow all the data of muscle and exercise gets deleted.
This is my muscle class
package com.fazla.exercise.model;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
#Entity
#JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
public class Muscle {
#Id
// #Column(unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column
private String name;
#OneToMany(mappedBy="muscle", cascade= CascadeType.ALL, fetch = FetchType.EAGER)
// #JoinColumn(name="muscle_id")
// #Column(nullable = true)
private List<Exercise> exercises = new ArrayList<>();
public Muscle() {
}
public Muscle(String name, List<Exercise> exercises) {
super();
this.name = name;
this.exercises = exercises;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Exercise> getExercises() {
return exercises;
}
public void setExercises(List<Exercise> exercises) {
this.exercises = exercises;
}
// #Override
// public String toString() {
// return "Muscle [id=" + id + ", name=" + name + ", exercises=" + exercises + "]";
// }
}
This is my Exercise Object
package com.fazla.exercise.model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
//import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
#Entity
//#JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
public class Exercise {
#Id
#Column(unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column
private String name;
#Column
private String description;
//As there will be many exercise under one muscle that is why manytoone
//object references an unsaved transient instance - save the transient instance before flushing
//that is why need to add the cascading dependencies
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="muscle_id")
// #JsonIgnore
// #JoinTable(name="muscle")
private Muscle muscle;
public Exercise() {
}
public Exercise(String name, String description, Muscle muscle) {
super();
this.name = name;
this.description = description;
this.muscle = muscle;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Muscle getMuscle() {
return muscle;
}
public void setMuscle(Muscle muscle) {
this.muscle = muscle;
}
// #Override
// public String toString() {
// return "Exercise [id=" + id + ", name=" + name + ", description=" + description + ", muscle=" + muscle + "]";
// }
}
This is the MuscleController
package com.fazla.exercise.controller;
import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.fazla.exercise.model.Muscle;
import com.fazla.exercise.repository.MuscleRepository;
#RestController
public class MuscleController {
private MuscleRepository muscleRepository;
public MuscleController(MuscleRepository muscleRepository) {
this.muscleRepository = muscleRepository;
}
#GetMapping("/muscle")
List<Muscle> all(){
return muscleRepository.findAll();
}
#PostMapping("/muscle")
Muscle newMuscle(#RequestBody Muscle muscle) {
return muscleRepository.save(muscle);
}
#GetMapping("/muscle/{id}")
Muscle one(#PathVariable Long id) {
return muscleRepository.findById(id)
.orElse(null);
}
#PutMapping("/muscle/{id}")
Muscle updateMuscle(#RequestBody Muscle newMuscle, #PathVariable Long id) {
return muscleRepository.findById(id)
.map(muscle ->{
muscle.setName(newMuscle.getName());
muscle.setExercises(newMuscle.getExercises());
return muscleRepository.save(muscle);
})
.orElse(null);
}
#DeleteMapping("/muscle/{id}")
void deleteMuscle(#PathVariable Long id){
muscleRepository.deleteById(id);
}
}
This is the ExerciseController Class
package com.fazla.exercise.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.fazla.exercise.model.Exercise;
import com.fazla.exercise.model.Muscle;
import com.fazla.exercise.repository.ExerciseRepository;
import com.fazla.exercise.repository.MuscleRepository;
#RestController
public class ExerciseController {
private ExerciseRepository repository;
private MuscleRepository muscleRepository;
#Autowired
public ExerciseController(ExerciseRepository repository, MuscleRepository muscleRepository) {
super();
this.repository = repository;
this.muscleRepository=muscleRepository;
}
#GetMapping("/exercise")
public List<Exercise> getAll() {
return repository.findAll();
}
#PostMapping("/exercise")
public Exercise newExercise(#RequestBody Exercise newExercise, #RequestParam
Long muscleId) {
Muscle muscle = muscleRepository.findById(muscleId).orElse(null);
newExercise.setMuscle(muscle);
return repository.save(newExercise);
}
#DeleteMapping("/exercise/{id}")
public void deleteExercise(#PathVariable Long id) {
repository.deleteById(id);
}
#GetMapping("/exercise/{id}")
public Exercise one(#PathVariable Long id) {
return repository.findById(id).orElse(null);
}
#PutMapping("/exercise/{id}")
public Exercise updateExercise(#RequestBody Exercise newExercise, #PathVariable Long id) {
return repository.findById(id)
.map(//map a function which maps
e ->{
e.setName(newExercise.getName());
e.setDescription(newExercise.getDescription());
e.setMuscle(newExercise.getMuscle());
return repository.save(e);
})
.orElse(null);
}
}
This is my ExerciseRepository
package com.fazla.exercise.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.fazla.exercise.model.Exercise;
public interface ExerciseRepository extends JpaRepository<Exercise, Long> {
}
This is the MuscleRepository
package com.fazla.exercise.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.fazla.exercise.model.Muscle;
public interface MuscleRepository extends JpaRepository<Muscle, Long>{
}
This is the error if I try the put request or update the exercise object
"timestamp": "2018-10-10T06:30:46.924+0000",
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: \n at [Source: (PushbackInputStream); line: 23, column: 1]Object id [1] (for `com.fazla.exercise.model.Muscle`) at [Source: (PushbackInputStream); line: 13, column: 28], Object id [1] (for `com.fazla.exercise.model.Muscle`) at [Source: (PushbackInputStream); line: 19, column: 28].",
"path": "/api/exercise/14"
The solution was, adding orphanRemoval= true on the Parent/ Muscle model
#OneToMany(mappedBy="muscle", cascade= CascadeType.ALL, orphanRemoval= true)
private List<Exercise> exercises = new ArrayList<>();
Removing the cascade= CascadeType.ALL in the child/ Exercise model
#ManyToOne
private Muscle muscle;
And for the updateExercise changing the Request by finding the muscle which the exercise belongs to and muscleRepository.findById(muscleId) and setting it in the new exercise object.
#PutMapping("/exercise/{id}")
public Exercise updateExercise(#RequestBody Exercise newExercise, #PathVariable Long id, #RequestParam Long muscleId) {
Muscle muscle = muscleRepository.findById(muscleId).orElse(null);
return repository.findById(id)
.map(//map a function which maps
e ->{
e.setName(newExercise.getName());
e.setDescription(newExercise.getDescription());
e.setMuscle(muscle);
return repository.save(e);
})
.orElse(null);
}
on your Exercise you have
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="muscle_id")
private Muscle muscle;
and on your Musce you have
#OneToMany(cascade= CascadeType.ALL)
private List<Exercise> exercises = new ArrayList<>();
Cascade.ALL propagates all actions on your Object and if you delete a Excercise, DELETE is propagated to all referenced objects
Bacause you just want to propagate UPDATES replace
cascade = CascadeType.ALL
with
cascade = CascadeType.SAVE_UPDATE

Spring JPA - mapping foreign keys as a primary key [MySQL]

I'm having problems in mapping foreign keys as the primary key.
My tables are:
client:
PK: id_client
games:
PK: id_game
tickets:
PK: (id_game_fk references game(id_game), id_client_fk references client(id_client))
And here are the classes I have defined as entities:
Client.java:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "client")
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id_client")
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Games.java:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "games")
public class Games {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id_game")
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Ticket.java:
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import Client;
import Games;
#Entity
#Table(name = "tickets")
public class Ticket implements Serializable {
private static final long serialVersionUID = 3287868602749718327L;
#EmbeddedId
private TicketId ticketId;
#ManyToOne
#JoinColumn(name = "id_game")
private Games games;
#ManyToOne
#JoinColumn(name = "id_client")
private Client client;
public TicketId getId() {
return ticketId;
}
public void setId(TicketId id) {
this.ticketId = id;
}
public Games getGames() {
return games;
}
public void setGames(Games games) {
this.games = games;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
}
TicketId.java:
import java.io.Serializable;
import javax.persistence.Embeddable;
#Embeddable
public class TicketId implements Serializable {
private static final long serialVersionUID = 6220676431741410239L;
private int idGameFk;
private int idClientFk;
public TicketId(int idGameFk, int idClientFk) {
this.idGameFk = idGameFk;
this.idClientFk = idClientFk;
}
public int getIdGameFk() {
return idGameFk;
}
public void setIdGameFk(int idGameFk) {
this.idGameFk = idGameFk;
}
public int getIdClientFk() {
return idClientFk;
}
public void setIdClientFk(int idClientFk) {
this.idClientFk = idClientFk;
}
}
I have tried all the advices I have found so far, but none of them helped. Also, I need this PK to be composed by foreign keys, so I really need help to solve out, how should I map it correctly.
You can use #MapsId :
#Entity
#Table(name = "tickets")
public class Ticket implements Serializable {
private static final long serialVersionUID = 3287868602749718327L;
#EmbeddedId
private TicketId ticketId;
#ManyToOne
#MapsId("idGameFk")
#JoinColumn(name = "id_game_fk")
private Games games;
#ManyToOne
#MapsId("idClientFk")
#JoinColumn(name = "id_client_fk")
private Client client;
....
}
More info here : http://docs.oracle.com/javaee/6/api/javax/persistence/MapsId.html

how to select an object from a list which is an attribute of another object in a database with spring

I have two classes where one of them contains a Map of objects of the second class, and I want to make a query to find one object by its id.
here's my code:
#Entity
#Table(name="objectx", uniqueConstraints=#UniqueConstraint(columnNames={"objectxId"}))
public class Objectx {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private int objectxId;
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name = "objectx_objecty", joinColumns = #JoinColumn(name = "objectxId") ,
inverseJoinColumns = #JoinColumn(name = "objectyId") )
#MapKeyColumn(name="objecty_name")
private Map<String, objecty> objectyMap;
in the objectyRepository, I have:
public interface ObjectyRepository extends CrudRepository<Objecty, Long> {
public static final String FIND_OBJECTY_BY_OBJECTYID_OBJECTXID =
"SELECT y from Objecty y "
+ "JOIN y.Objectx x "
+ "WHERE x.objectxId =:objectxId "
+ "AND y.objectyId =:objectyId";
#Query(FIND_OBJECTY_BY_OBJECTYID_OBJECTXID)
public Objecty findObjectyByObjectyIdAndObjectxId(#Param("ObjectxId")
int ObjectxId, #Param("ObjectyId") String ObjectyId);
Can anyone tell me how to get the needed result, please?
I'm working with eclipse Kepler and using spring and hibernate
the error I get is:
Caused by: org.hibernate.QueryException: could not resolve property: Objectx of: com.domain.Objecty
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1978)
at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:367)
at org.hibernate.hql.internal.ast.tree.FromElement.getPropertyType(FromElement.java:500)
at org.hibernate.hql.internal.ast.tree.DotNode.getDataType(DotNode.java:649)
at org.hibernate.hql.internal.ast.tree.DotNode.prepareLhs(DotNode.java:272)
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:219)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:126)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:386)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3858)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3644)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3522)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:706)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:562)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
... 80 common frames omitted
Here's the two classes:
package com.domain;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
#Entity
#Table(name="objecty", uniqueConstraints=#UniqueConstraint(columnNames={"objectyId"}))
public class Objecty {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#Column(name="objectyId")
private String objectyId;
private String objectyName;
#ManyToMany(mappedBy="objectyMap")
private Set<Objectx> objectxSet = new HashSet<Objectx>(0);
public Objecty(){
}
public String getObjectyId(){
return objectyId;
}
public void settObjectyId(String objectyId){
this.objectyId = objectyId;
}
public String getObjectyName(){
return objectyName;
}
public void setObjectyName(String objectyName){
this.objectyName = objectyName;
}
public Set<Objectx> getObjectx() {
return objectxSet;
}
public void setObjectxSet(Set<Objectx> objectxSet) {
this.objectxSet = objectxSet;
}
}
and:
package com.domain;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.MapKeyColumn;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
#Entity
#Table(name="objectx", uniqueConstraints=#UniqueConstraint(columnNames={"objectxId"}))
public class Objectx {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private int objectxId;
private String type;
private String model;
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name = "objectx_objecty", joinColumns = #JoinColumn(name = "objectxId") ,
inverseJoinColumns = #JoinColumn(name = "objectyId") )
#MapKeyColumn(name="objectyMap")
private Map<String, Objecty> objectyMap;
public Objectx(){
objectyMap = new HashMap<String, Objecty>();
}
public long getId() {
return id;
}
public int getobjectxId(){
return objectxId;
}
public void setObjectxId(int objectxId){
this.objectxId = objectxId;
}
public String getType(){
return type;
}
public void setType(String type){
this.type = type;
}
public String getModel(){
return model;
}
public void setModel(String model){
this.model = model;
}
public Map<String, Objecty> getObjectyMap(){
if(objectyMap==null){
this.objectyMap = new HashMap<String, Objecty>();
}
return objectyMap;
}
public void addOrUpdateObjectyToObjectx(Objecty objecty){
String objectyId = objecty.getObjectyId();
if (objectyMap.containsKey(objectyId)){
Objecty objectyTmp = objectyMap.get(objectyId);
objectyTmp = objecty;
} else{
objectyMap.put(objectyId, objecty);
}
}
}
The error is clearly stating that that the 'Objecty' class does not have the 'Objectx' that you are trying to use on the join 'JOIN y.Objectx'.
Try to switch this JOIN syntax by the following:
JOIN y.objectxSet
Doing this your query should be able to execute.
However, reading your code I could see a lot of confused attribute declarations and mappings, it's even hard to understand your real problem, and/or verify if it will work properly or not.
Naming your classes by the their exact behavior is almost a MUST DO thing while coding Java, even in studies and tests.
By the way, don't get me wrong, I'm just saying what's my opinion about your code organization, and stating something you could improve. There's tons of materials about Java/Hibernate mapping that will surely help you to understand it's behavior.
Going back to your question, let us know if the solution stated above will help you in this error.

One To Many Relation in Hibernate / JPA

iam new to hibernate,iam using two classes which have person and section but iam able to relate them, iam getting like Exception in thread "main" org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class: in.quadra.apps.Profile.Sections[in.quadra.apps.Section]
Person.java
package in.quadra.apps;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="Profile")
public class Profile {
#Id
#GeneratedValue
#Column(name="Profile_ID")
private Long ProfileId;
#Column(name="Profile_NAME")
private String ProfileName;
#OneToMany(mappedBy="Profile")
private Set<Section> Sections;
public Long getProfileId() {
return ProfileId;
}
public void setProfileId(Long profileId) {
ProfileId = profileId;
}
public String getProfileName() {
return ProfileName;
}
public void setProfileName(String profileName) {
ProfileName = profileName;
}
public Set<Section> getSections() {
return Sections;
}
public void setSections(Set<Section> sections) {
Sections = sections;
}
}
Section.Java
package in.quadra.apps;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="Profile")
public class Profile {
#Id
#GeneratedValue
#Column(name="Profile_ID")
private Long ProfileId;
#Column(name="Profile_NAME")
private String ProfileName;
#OneToMany(mappedBy="Profile")
private Set<Section> Sections;
public Long getProfileId() {
return ProfileId;
}
public void setProfileId(Long profileId) {
ProfileId = profileId;
}
public String getProfileName() {
return ProfileName;
}
public void setProfileName(String profileName) {
ProfileName = profileName;
}
public Set<Section> getSections() {
return Sections;
}
public void setSections(Set<Section> sections) {
Sections = sections;
}
}
main.java
package in.quadra.apps;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Main123 {
public static void main(String ar[]){
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
Profile p= new Profile();
p.setProfileName("Srikanth");
Section s1= new Section();
s1.setSectionName("Names");
s1.setProfileId(p);
Section s2= new Section();
s2.setProfileId(p);
s2.setSectionName("Address");
session.save(p);
// session.save(s1);
// session.save(s2);
session.getTransaction().commit();
session.close();
}
}
Probably missing #Entity on Section class.

Categories

Resources