Mapstruct bidirectional mapping throwing out of memory error - java

//Entities and DTOs
public class JourneyType implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "journey_type_id")
private Long journeyTypeId;
private String type;
// bi-directional many-to-one association to JourneyRent
#OneToMany(mappedBy = "journeyType")
private Set<JourneyRent> journeyRents;
}
public class JourneyTypeTO implements Serializable {
private Long journeyTypeId;
private String type;
private Set<JourneyRentTO> journeyRents;
}
public class JourneyRent implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "journey_rent_id")
private Long journeyRentId;
#Column(name = "min_max_travel_km")
private Double minMaxTravelKm;
#Column(name = "rent_charges")
private BigDecimal rentCharges;
// bi-directional many-to-one association to JourneyType
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "journey_type_id")
private JourneyType journeyType;
// bi-directional many-to-one association to VehicleType
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "vehicle_type_id")
private VehicleType vehicleType;
}
public class JourneyRentTO implements Serializable {
private Long journeyRentId;
private Double minMaxTravelKm;
private BigDecimal rentCharges;
private JourneyTypeTO journeyType;
private VehicleTypeTO vehicleType;
}
public class VehicleType implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="vehicle_type_id")
private Long vehicleTypeId;
private String type;
//bi-directional many-to-one association to JourneyRent
#OneToMany(mappedBy="vehicleType")
private Set<JourneyRent> journeyRents;
}
public class VehicleTypeTO implements Serializable {
private Long vehicleTypeId;
private String type;
private Set<JourneyRentTO> journeyRents;
}
// Mapper interfaces
#Mapper(uses = {JourneyRentMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface JourneyTypeMapper {
JourneyTypeMapper INSTANCE = Mappers.getMapper(JourneyTypeMapper.class);
#Mapping(target = "journeyBookings", ignore = true)
JourneyTypeTO toDTO(JourneyType journeyType, #Context CycleAvoidingMappingContext cycleAvoidingMappingContext);
#Mapping(target = "journeyBookings", ignore = true)
JourneyType toEntity(JourneyTypeTO journeyType);
}
#Mapper(uses = {JourneyTypeMapper.class, VehicleTypeMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface JourneyRentMapper {
JourneyRentMapper INSTANCE = Mappers.getMapper(JourneyRentMapper.class);
#Mapping(target = "journeyType", ignore = true)
JourneyRentTO toDTO(JourneyRent journeyRent, #Context CycleAvoidingMappingContext cycleAvoidingMappingContext);
#Mapping(target = "journeyBookingVehicles", ignore = true)
JourneyRent toEntity(JourneyRentTO journeyRentTo);
}
#Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface VehicleTypeMapper {
VehicleTypeMapper INSTANCE = Mappers.getMapper(VehicleTypeMapper.class);
VehicleTypeTO toDTO(VehicleType vehiType);
VehicleType toEntity(VehicleTypeTO vehiTypeTo);
}
public class CycleAvoidingMappingContext {
private final Map<Object, Object> knownInstances = new IdentityHashMap<>();
#BeforeMapping
public <T> T getMappedInstance(Object source, #TargetType Class<T> targetType) {
return targetType.cast(knownInstances.get(source));
}
#BeforeMapping
public void storeMappedInstance(Object source, #MappingTarget Object target) {
knownInstances.put(source, target);
}
}
There is a bi-directional relationship between JourneyType and JourneyRent. Now JPQL query returns JourneyType Object which has a reference of
JourneyRent object and in turn JourneyRent object has a reference of JourneyType Object.
Usage :
List<JourneyTypeTO> journeyTypeTos = new ArrayList<>();
for (JourneyType journeyType : journeyTypes) {
journeyTypeTos.add(JourneyTypeMapper.INSTANCE.toDTO(journeyType, new CycleAvoidingMappingContext()));
}
When I try to map Entity to TO, I'm getting out of memory error. How can I map the objects for this scenario ?

I see that you are using the example of the CycleAvoidingMappingContext. The reason why it isn't working to you is because you are not passing it in your VehicleMapper. MapStruct will use the VehicleMapper to map your vehicles and there is no context that would store the cycles.

Related

JPA OneToMany with Parent composite pk is part of child primary key Derived Entity issue

One To Many with Parent composite primary key is part of child primary key issue. Throwing Exceptions with the below code snippets
Sample JSON Embedded Data as follows:
{
"pt_reg_no": "1000", //Serial number generation
"game_year": "G12021",
"name": "myname",
"eventDetails": [{
"major_event_code": "A",
"sub_event_code": "A7",
"category_code": "MO"
},
{
"major_event_code": "B",
"sub_event_code": "B7",
"category_code": "WO"
}
]
}
Participant can register for multiple Events:
Participant (Composite Key) - pt_reg_no, game_year
EventDetails (Composite Key) - pt_reg_no, game_year, sub_event_code, category_code
//Parent Class IDclass
public class ParticipantKey implements Serializable {
private Long pt_reg_no;
private String game_year;
}
#IdClass(ParticipantKey.class)
public class ParticipantModel {
#Id
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "participantseq"
)
#SequenceGenerator(
name = "participantseq",
allocationSize = 1
)
private Long pt_reg_no;
#Id
private String game_year = 'G12021';
#OneToMany(mappedBy = "participantModel", orphanRemoval = true, cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
private Set<EventDetailsModel> eventDetails = new HashSet<>();
public Set<EventDetailsModel> getEventDetails() {
return eventDetails;
}
public void setEventDetails(Set<EventDetailsModel> eventDetails) {
this.eventDetails = eventDetails;
for (EventDetailsModel b : eventDetails) {
b.setParticipantModel(this);
}
}
}
//Child class IDclass
public class ParticipantEventDetailsId implements Serializable {
private ParticipantKey participantModel;
private String sub_event_code;
private String category_code;
}
public class EventDetailsModel {
#Id
#Column(name = "sub_event_code")
private String sub_event_code;
#Id
#Column(name = "category_code")
private String category_code;
#Id
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumns({
#JoinColumn(name = "pt_reg_no", referencedColumnName = "pt_reg_no"),
#JoinColumn(name = "game_year", referencedColumnName = "game_year")
})
private ParticipantModel participantModel;
public ParticipantModel getParticipantModel() {
return participantModel;
}
public void setParticipantModel(ParticipantModel participantModel) {
this.participantModel = participantModel;
}
}
//---------------------------------------------------
//JSON input data received into ParticipantModel from #requestBody
public class FormDataObjects {
private ParticipantModel formData;
#JsonCreator
public FormDataObjects(ParticipantModel formData) {
this.formData = formData;
}
}
//Controller Entry point
#RequestMapping(path = "/participantData", method = RequestMethod.POST)
#Transactional
public ResponseEntity<?> participantRegistration(#Valid #RequestBody FormDataObjects values) {
ParticipantModel participant = values.getFormData();
participant.setGame_year(new SimpleDateFormat("yyyy").format(new Date()) + GenricData.game);
ParticipantModel person = participantRepository.save(participant);
if (person == null) {
return ResponseEntity.ok("Participant is not inserted");
} else {
Set<EventDetailsModel> eventDetails = participant.getEventDetails();
if (eventDetails.size() > 0) {
eventDetails.forEach(event -> {
//event.setPt_reg_no(person.getPt_reg_no());
//event.setGame_year(person.getGame_year());
//event.setParticipantModel(participant);
entityManager.persist(event);
entityManager.flush();
entityManager.clear();
});
}
}
return ResponseEntity.ok("inserted");
}
You can try a "derived identity" by mapping your details class like this:
public class ParticipantEventDetailsId implements Serializable {
private String sub_event_code;
private String category_code;
private ParticipantKey participantModel; // matches name of attribute and type of ParticipantModel PK
}
public class EventDetailsModel {
#Id
#Column(name = "sub_event_code")
private String sub_event_code;
#Id
#Column(name = "category_code")
private String category_code;
#Id
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumns({
#JoinColumn(name = "pt_reg_no", referencedColumnName = "pt_reg_no"),
#JoinColumn(name = "game_year", referencedColumnName = "game_year")
})
private ParticipantModel participantModel;
}
Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.
Alternative solution to OneToMany mapping when parent has composite key and serial number generation is also required at parent
Use #Transient annotation at Set or List Child Entities
1)save Parent entity with above annotation helps jpa to skip List/Set of EventsDetailsModel from saving
2) Iterate Child and get Parent composite key values which are already saved and persist child data along with childs key attributes.
//Parent Class IDclass
public class ParticipantKey implements Serializable {
private Long pt_reg_no;
private String game_year;
}
#IdClass(ParticipantKey.class)
public class ParticipantModel {
#Id
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "participantseq"
)
#SequenceGenerator(
name = "participantseq",
allocationSize = 1
)
private Long pt_reg_no;
#Id
private String game_year = 'G12021';
#Transient //Find exact path for Transient
private Set<EventDetailsModel> eventDetails = new HashSet<>();
public Set<EventDetailsModel> getEventDetails() {
return eventDetails;
}
}
//Child class IDclass
public class ParticipantEventDetailsId implements Serializable {
private Long pt_reg_no;
private String game_year;
private String sub_event_code;
private String category_code;
}
public class EventDetailsModel {
#Id
#Column(name = "sub_event_code")
private String sub_event_code;
#Id
#Column(name = "category_code")
private String category_code;
#Id
private Long pt_reg_no;
#Id
private String game_year;
}
//---------------------------------------------------
//JSON input data received into ParticipantModel from #requestBody
public class FormDataObjects {
private ParticipantModel formData;
#JsonCreator
public FormDataObjects(ParticipantModel formData) {
this.formData = formData;
}
}
//Controller Entry point
#RequestMapping(path = "/participantData", method = RequestMethod.POST)
#Transactional
public ResponseEntity<?> participantRegistration(#Valid #RequestBody FormDataObjects values) {
ParticipantModel participant = values.getFormData();
participant.setGame_year(new SimpleDateFormat("yyyy").format(new Date()) + GenricData.game);
ParticipantModel person = participantRepository.save(participant);
if (person == null) {
return ResponseEntity.ok("Participant is not inserted");
} else {
Set<EventDetailsModel> eventDetails = participant.getEventDetails();
if (eventDetails.size() > 0) {
eventDetails.forEach(event -> {
event.setPt_reg_no(person.getPt_reg_no());
event.setGame_year(person.getGame_year());
entityManager.persist(event);
entityManager.flush();
entityManager.clear();
});
}
}
return ResponseEntity.ok("inserted");
}

How to get object from OneToMany collection of objects?

I have an Order entity and OrderProduct. I want to show order details on frontend and of course order products in it. So how to fetch product object in OrderProduct JSON. I'm missing product object in products array. I don't need order object one more time and i think it going to be a infinite recursion stuff with it. :)
My Order entity:
#Entity
#Getter
#Setter
#Table(name ="orders")
public class Order{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
private BigDecimal totalPrice;
#OneToMany(mappedBy = "order", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JsonManagedReference(value="orders")
private List<OrderProduct> products = new ArrayList<>();
private int userId;
#DateTimeFormat(pattern="dd/MM/yyyy")
private Date date = new Date();
#DateTimeFormat(pattern="dd/MM/yyyy")
private Date deliveryDate;
#Enumerated(EnumType.STRING)
private OrderType orderType;
}
My OrderProduct entity:
#Entity
#Setter
#Getter
public class OrderProduct {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(fetch = FetchType.EAGER)
#JsonBackReference(value="product")
#JoinColumn(name = "product_id")
private Product product;
#ManyToOne
#JsonBackReference(value="orders")
#JoinColumn(name = "order_id")
private Order order;
private Integer quantity;
}
Product entity:
#Entity
#Getter
#Setter
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(unique = true)
private String name;
private double price;
#OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
#JsonManagedReference(value="ingredients")
private List<Ingredient> ingredients = new ArrayList<>();
#OneToMany(mappedBy = "product",fetch = FetchType.EAGER)
#JsonManagedReference(value="product")
private List<OrderProduct> products = new ArrayList<>();
private String fileName;
}
This can help annotate one of your entity clases with
#JsonIdentityInfo(
property = "id",
generator = ObjectIdGenerators.PropertyGenerator.class
)
Every time when JSON serialization go in circles object data will be replaced with object id or orher field of entity for your choose.
You can use #JsonViewannotation to define the fields that you need to serialize to JSON
How it works:
You need define class with interfaces. For example:
public class SomeView {
public interface id {}
public interface CoreData extends id {}
public interface FullData extends CoreData {}
}
Mark entity fields with #JsonView(<some interface.class>)
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonView(SomeView.id.class)
private Long id;
#Column(nullable = false)
#JsonView(SomeView.CoreData.class)
private String username;
#Column(nullable = false)
#JsonView(SomeView.FullData.class)
private String email;
}
Annotate endpoint with #JsonView(<some interface.class>)
#GetMapping()
#JsonView(<some interface.class>)
public User getUser() {
return <get user entity somwhere>
}
In case #JsonView(SomeView.id.class) you will get this JSON:
{
id: <some id>
}
In case #JsonView(SomeView.CoreData.class):
{
id: <some id>,
username: <some username>
}
In case #JsonView(SomeView.FullData.class):
{
id: <some id>,
username: <some username>,
email: <some email>
}
#JsonView also works with embeded objects and you can annotate one field with multiply views classes - #JsonView({SomeView.FullData.class, SomeOtherView.OtherData.class})
In your case i think you should annotate all the fields you need except:
#OneToMany(mappedBy = "product",fetch = FetchType.EAGER)
#JsonManagedReference(value="product")
private List<OrderProduct> products = new ArrayList<>();
in Product
to avoid circular serialization
Or as alternative you can just use DTO classes or seralize oject to JSON manualy (https://thepracticaldeveloper.com/java-and-json-jackson-serialization-with-objectmapper/)
This can be done by my library beanknife
// This configure generate a class named ProductInfo which has the same shape with Product without property "products"
#ViewOf(value = Product.class, genName="ProductInfo", includePattern = ".*", excludes = {"products"})
class ProductInfoConfigure {}
// This configure generate a class named OrderProductRelation with the same shape of OrderProduct.
// But it has not order property and the type of its product property is change to ProductInfo generated above.
#ViewOf(value = OrderProduct.class, genName="OrderProductRelation", includePattern = ".*", excludes = {"order"})
class OrderProductRelationConfigure {
#OverrideViewProperty("product")
private ProductInfo product;
}
// This configure generate a class named OrderDetail with the same shape of Order.
// But the type of its products property is change to List<OrderProductRelation>
#ViewOf(value = Order.class, genName="OrderDetail", includePattern = ".*")
class OrderDetailConfigure {
#OverrideViewProperty("products")
private List<OrderProductRelation> products;
}
will generate these classes:
class ProductInfo {
private Long id;
private String name;
private double price;
private List<Ingredient> ingredients; // it is not processed because you have not provide the class Ingredient
private String fileName;
}
public class OrderProductRelation {
private Long id;
private ProductInfo product;
private Integer quantity;
}
public class OrderDetail {
public Long id;
private BigDecimal totalPrice;
private List<OrderProductRelation> products;
private int userId;
private Date date = new Date();
private Date deliveryDate;
private OrderType orderType;
}
Then
Order order = ...
OrderDetail orderDetail = OrderDetail.read(order);
// serialize the otherDetail instead of order.
List<Order> orders = ...
List<OrderDetail> orderDetails = OrderDetail.read(orders);
// serialize the orderDetails instead of orders.
Possible problems:
I doesn't use Lombok, so Lombok may need to be adapted because it change the byte code on the fly. But it is not a big problem, I will try to adapt it if someone commit the issue and provide enough use cases.
The generated class does not inherit the annotation on the original class. In next release I will provide a sulotion. At this moment, as a workaround, we can use custom method to convert the property manually. such as
#ViewOf(value = Order.class, genName="OrderDetail", includePattern = ".*")
class OrderDetailConfigure {
#OverrideViewProperty("products")
private List<OrderProductRelation> products;
#OverrideViewProperty("orderType")
public static String orderType(Order source) {
return source.getOrder().name();
}
}
The generated class will be changed to
public class OrderDetail {
public Long id;
private BigDecimal totalPrice;
private List<OrderProductRelation> products;
private int userId;
private Date date = new Date();
private Date deliveryDate;
private String orderType;
}
Update
Version 1.2.0 released. Add support of annotation inheritance.
#ViewOf(value = Order.class, genName="OrderDetail", includePattern = ".*")
#UseAnnotation({DateTimeFormat.class, Enumerated.class, JsonProperty.class})
class OrderDetailConfigure {
#OverrideViewProperty("products")
private List<OrderProductRelation> products;
}
generate
public class OrderDetail {
public Long id;
private BigDecimal totalPrice;
private List<OrderProductRelation> products;
private int userId;
#DateTimeFormat(pattern="dd/MM/yyyy")
private Date date;
#DateTimeFormat(pattern="dd/MM/yyyy")
private Date deliveryDate;
#Enumerated(EnumType.STRING)
private OrderType orderType;
}

One to Many Relation mapping using org.mapstruct framework

How can I map the one to many relationship using org.mapstruct framework?
DTO classes:
#Data
public class ScheduledJobDTO {
private String jobName;
private String jobGroup;
private String jobClass;
private String cronExpression;
private Boolean cronJob;
private Long repeatTime;
private Integer repeatCount;
private Set<ScheduledJobParamsDTO> paramtersDTOs;
}
#Data
#EqualsAndHashCode
public class ScheduledJobParamsDTO {
String name;
String value;
}
Domain Classes -
#Data
#Entity
#Table(name = "scheduled_job")
public class ScheduledJob {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "job_name")
private String jobName;
#Column(name = "job_group")
private String jobGroup;
#Column(name = "job_class")
private String jobClass;
#Column(name = "cron_expression")
private String cronExpression;
#Column(name = "is_cron_job")
private Boolean cronJob;
#Column(name = "repeat_time")
private Long repeatTime;
#Column(name = "repeat_count")
private Integer repeatCount;
#Column(name = "trigger_start_date")
private LocalDate triggerStartDate;
#Column(name = "trigger_end_date")
private LocalDate triggerEndDate;
#Column(name = "created_at")
private LocalDate createdAt;
#Column(name = "modified_at")
private LocalDate modifiedAt;
#Column(name = "is_active")
private Boolean active;
#OneToMany(mappedBy = "scheduledJob")
private Set<ScheduledJobParams> parameters;
}
#Data
#Entity
#Table(name = "scheduled_job_params")
#EqualsAndHashCode
public class ScheduledJobParams {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "scheduled_job_id", nullable = false)
ScheduledJob scheduledJob;
String name;
String value;
}
Mapper Class -
#Mapping(source = ".", target = ".")
#Mapping(source = "paramtersDTOs", target = "parameters")
ScheduledJob mapToDomain(ScheduledJobDTO scheduledJobDTO);
Now, the above mapper is mapping the ScheduledJob & ScheduledJobParams, but the ScheduledJobParams has reference of ScheduledJob.
How can I map the reference ScheduledJob to ScheduledJobParams?
You can achieve that through #AfterMapping with #MappedTarget. This is described in the reference documentation: 12.2. Mapping customization with before-mapping and after-mapping methods.
// Java 8+ otherwise you need to use an abstract class and a for-loop instead
#Mapper(componentModel = "spring")
public interface ScheduledJobMapper {
#Mapping(target = "parameters", source = "paramtersDTOs")
ScheduledJob mapToDomain(ScheduledJobDTO dto);
#AfterMapping
default void after(#MappingTarget ScheduledJob domain, ScheduledJobDTO dto) {
domain.getParameters().forEach(scheduledJobParams -> {
scheduledJobParams.setScheduledJob(domain);
});
}
}
However, I am sure you don't need to fill the bidirectional relationship when you map back from the DTO into the entity (this is what I understand as you refer to "domain"). Note printing out or serializing such object i.e. into JSON or XML throws java.lang.StackOverflowError if not properly handled.

DTO to entity mapping when entity has many to one relationship

I'm trying to map business object into entity but got stuck and have no idea how to resolve this.
The problem is when I try to map these attributes from DTO which are attributes of many-to-one relationship with another table.
Here is how my Entity looks like:
#Entity
#Table(name = "t_car")
public class Car extends AbstractEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
#Column(name = "pkIdCar")
private Long id;
#Column(nullable = false, columnDefinition="VARCHAR(45)")
private String brand;
#Column(nullable = false)
private Integer productionYear;
#Column(nullable = false)
private Float engineCapacity;
#Column(nullable = false)
private Float power;
#Column(nullable = false)
private Integer distance;
#ManyToOne
#JoinColumn(name = "fkIdType")
private CarType carType;
#ManyToOne
#JoinColumn(name = "fkIdColor")
private Color color;
... }
And here is DTO:
public class CarDto {
private Long id;
private String brand;
private Integer productionYear;
private Float engineCapacity;
private Float power;
private Integer distance;
private CarTypes carType;
private ColorTypes color;
... }
CarTypes and ColorTypes are enums which have assigned number corresponding to their primary key in database. For example CarTypes is:
REGULAR_TWO_DOOR(1),
REGULAR_FOUR_DOOR(2),
STATION_WAGON(3),
MINIVAN(4),
SPORT(5),
LUXURY(6);
And here is the mapper i managed to write. How can I assign proper CarType (that's entity) to carEntity basing on CarType primary key?
public class CarMapper {
...
public static Car carDtoToCar(CarDto carDto, Car carEntity) {
if(carEntity == null) {
carEntity = new Car();
}
carEntity.setBrand(carDto.getBrand());
carEntity.setProductionYear(carDto.getProductionYear());
carEntity.setEngineCapacity(carDto.getEngineCapacity());
carEntity.setPower(carDto.getPower());
carEntity.setDistance(carDto.getDistance());
Long carTypeId = Long.valueOf(carDto.getCarType().getNumber());
Long carColorId = Long.valueOf(carDto.getColor().getNumber());
/* ? */
return carEntity;
}
}
CarType entity:
#Entity
#Table(name = "t_car_type")
public class CarType extends AbstractEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
#Column(name = "pkIdType")
private Long id;
#Enumerated(EnumType.STRING)
#Column(nullable = false, columnDefinition="VARCHAR(45)")
private CarTypes type;
... }
Get the CarType entity based on the Cartype Id. For example:
CarType carType = entityManager.find(CarType.class, carTypeId);
And then set this carType in CarEntity as
carEntity.setCarType(carType);

Mapping issue on Hibernate annotation

I have the above tables i need to write the HIbernate entity class with annotation
and mapping
i have a problem while getting the List of ObjectAttributes..
Class are written as below
#Entity
public class Object {
#Id
private int id;
private String name;
#OneToMany(mappedBy="object",fetch=FetchType.LAZY)
private List<ObjectAttribute> attrubuteList;
}
#Entity
public class ObjectAttribute {
#Id
private int id;
#ManyToOne
#JoinColumn(name="objectId")
private Object object;
private String name;
}
#Entity
public class Filter {
#Id
private int filterId;
#ManyToOne
#JoinColumn(name="ObjectId")
private Object object;
private String filterName;
#OneToMany(mappedBy="filter")
private Set<FilterAttribute> filterValues;
}
#Entity
public class FilterAttribute implements Serializable {
#Id
private int filterAttrId;
#Id
#ManyToOne
#JoinColumn(name="objectId")
private Object object;
#Id
#ManyToOne
#JoinColumn(name="filterId")
private Filter filter;
#Id
#ManyToOne
#JoinColumn(name="attributeId")
private ObjectAttribute attribute;
private String value;
}
Note not added getter and setters
and test code as below
List<Object> list = sess.createCriteria(Object.class).list();
for(Object ob: list)
{
System.out.println("Object name : "+ ob.getName());
List<ObjectAttribute> attList = ob.getAttrubuteList();
for (Iterator iterator = attList.iterator(); iterator.hasNext();) {
ObjectAttribute objectAttribute = (ObjectAttribute) iterator
.next();
System.out.println(objectAttribute.getName());
}
}
attList = ob.getAttrubuteList(); returns null
While creating the Object in my test code as below
Object obj = new Object();
obj.setId(1);
obj.setName("Employee");
sess.save(obj);
ObjectAttribute ageAtt = new ObjectAttribute();
ageAtt.setId(1);
ageAtt.setName("age");
ageAtt.setObject(obj);
sess.save(ageAtt);
ObjectAttribute depAtt = new ObjectAttribute();
depAtt.setId(2);
depAtt.setName("department");
depAtt.setObject(obj);
sess.save(depAtt);
ObjectAttribute attName = new ObjectAttribute();
attName.setId(3);
attName.setName("name");
attName.setObject(obj);
sess.save(attName);
I have not added these line
obj.getAttrubuteList().add(depAtt);
obj.getAttrubuteList().add(attName);
obj.getAttrubuteList().add(ageAtt);
But i dont know why we need to do this!!

Categories