How to map multiple classes to one table in JPA? - spring-boot

I know this is a frequently asked question, but I couldn't find any answers because I have 3 classes and I generally have problems to build the given structure:
type OrderItem = {
count: number,
price: number,
order: number,
subItems: {
count: number,
name: string,
price: number,
extraItems: {
count: number,
name: string,
price: number,
}
}
};
This is my try at doing it in Java with JPA:
Order.java
package de.gabriel.mcdonaldsproject.models;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
#Entity
#Table(name = "orders", schema = "public")
public class Order implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_generator")
#SequenceGenerator(name = "order_generator", sequenceName = "order_seq")
private long id;
private List<Item> products; // <--------- 'Basic' attribute type should not be a container
public Order() {
}
public Order(List<Item> products) {
this.products = products;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public List<Item> getProducts() {
return products;
}
public void setProducts(List<Item> product) {
this.products = product;
}
}
Item.java
package de.gabriel.mcdonaldsproject.models;
import javax.persistence.*;
public class Item{
private double count;
private double price;
private double order;
private SubItems subItems;
public Item(){}
public Item(double count, double price, double order, SubItems subItems) {
this.count = count;
this.price = price;
this.order = order;
this.subItems = subItems;
}
public double getCount() {
return count;
}
public void setCount(double count) {
this.count = count;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getOrder() {
return order;
}
public void setOrder(double order) {
this.order = order;
}
public SubItems getSubItems() {
return subItems;
}
public void setSubItems(SubItems subItems) {
this.subItems = subItems;
}
}
SubItems.java
package de.gabriel.mcdonaldsproject.models;
import javax.persistence.*;
import java.util.List;
public class SubItems {
private double count;
private String name;
private double price;
private List<String> extraItems;
public SubItems(){}
public SubItems(double count, String name, double price, List<String> extraItems) {
this.count = count;
this.name = name;
this.price = price;
this.extraItems = extraItems;
}
public double getCount() {
return count;
}
public void setCount(double count) {
this.count = count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public List<String> getExtraItems() {
return extraItems;
}
public void setExtraItems(List<String> extraItems) {
this.extraItems = extraItems;
}
}
Does someone have an idea on how to rebuild this structure in Java with JPA so it also gets saved in the database?

If this object orderitem is not going to expand, I would suggest JSON string saving in the database.
OR you can do following mappings:
#OneToMany(mappedBy="order")
public Order(List<Item> products) {
this.products = products;
}
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "subitem_id", referencedColumnName = "id")
private SubItems subItems;

Update the following information like this :
#Embeddable
public class Item {
// .....
#Embedded
private SubItems subItems;
//.......
}
#Embeddable
public class SubItems {
// .....
#ElementCollection
private List<String> extraItems;
//.......
}
#Entity
#Table(name = "orders", schema = "public")
public class Order implements Serializable {
//.....
#ElementCollection
private List<Item> products;
//.......
}

Related

Criteria Api generetes too much joins

Entities:
#Entity
#Table(name = "shop")
public class Shop implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String address;
#OneToMany(mappedBy = "shop")
private List<Product> product = new ArrayList<>();
public Shop() {
}
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 getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
#Entity
#Table(name = "product")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "disc_col")
public class Product implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private BigDecimal price;
#ManyToOne
private Shop shop;
public Product() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Shop getShop() {
return shop;
}
public void setShop(Shop shop) {
this.shop = shop;
}
}
#Entity
#DiscriminatorValue("loose")
public class LooseProduct extends Product {
private BigDecimal weight;
public LooseProduct() {
}
public BigDecimal getWeight() {
return weight;
}
public void setWeight(BigDecimal weight) {
this.weight = weight;
}
}
#Entity
#DiscriminatorValue("liquid")
public class LiquidProduct extends Product {
private BigDecimal volume;
public LiquidProduct() {
}
public BigDecimal getVolume() {
return volume;
}
public void setVolume(BigDecimal volume) {
this.volume = volume;
}
}
Service:
public class ShopRepositoryImpl implements ShopRepositoryCustom{
#PersistenceContext
private EntityManager em;
#Override
public List<Shop> findShops(BigDecimal volume, BigDecimal weight, BigDecimal price) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Shop> cq = cb.createQuery(Shop.class);
Root<Shop> root = cq.from(Shop.class);
Join<Shop, Product> product = root.join("product", JoinType.LEFT);
Predicate p1 = cb.equal(cb.treat(product, LiquidProduct.class).get("volume"), volume);
Predicate p2 = cb.equal(cb.treat(product, LooseProduct.class).get("weight"), weight);
Predicate p3 = cb.equal(product.get("price"), price);
cq.where(cb.and(p3, cb.or(p1, p2)));
Query q = em.createQuery(cq);
return q.getResultList();
}
}
I have a problem that my query findShops generates too much joins:
select shop0_.id as id1_1, shop0_.address as address2_1, shop0_.name as name3_1 from shop shop0
left outer join product product1 on shop0_.id=product1_.shop_id
left outer join product product2 on shop0_.id=product2_.shop_id
left outer join product product3_ on shop0_.id=product3_.shop_id where product3_.price=1 and (product2_.volume=1 or product3_.weight=0)
It is InheritanceType.SINGLE_TABLE strategy so it shouldn't create three joins because there is just one table Product in database. Is there any way to optimize this?
Code from org.hibernate.query.criteria.internal.CriteriaBuilderImpl class:
#SuppressWarnings("unchecked")
private <X, T, V extends T, K extends JoinImplementor> K treat(
Join<X, T> join,
Class<V> type,
BiFunction<Join<X, T>, Class<V>, K> f) {
final Set<Join<X, ?>> joins = join.getParent().getJoins();
final K treatAs = f.apply( join, type );
joins.add( treatAs );
return treatAs;
}
The treat method creates new join from existing one. It is happening every time independent of inheritence type.
Next hibernate generates query and do not check duplicates in joins.
Do you have any idea how to prevent from generate additional joins when we use treat method?
I found the error report:
https://hibernate.atlassian.net/projects/HHH/issues/HHH-12094?filter=allissues&orderby=created%20DESC&keyword=treat
If you use JPA 2.1 onwards you can change the query like this:
select shop0_.id as id1_1, shop0_.address as address2_1, shop0_.name as name3_1
from shop shop0
left join product product1 on shop0_.id=product1_.shop_id
and (
(product1.disc_col = 'loose' and product1.weight = weight_var)
or (product1.disc_col = 'liquid' and product1.volume = volume_var)
);
For the implementation you would need to add the mapping of the disc_col column to the Product entity.
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Shop> cq = cb.createQuery(Shop.class);
Root<Shop> root = cq.from(Shop.class);
Join<Shop, Product> product = root.join("product", JoinType.LEFT);
//add other conditions
product.on(
cb.and(
cb.or(
cb.and(cb.equal(product.get("discCol"),"liquid"),cb.equal(product.get("volume"),volumeVar)),
cb.and(cb.equal(product.get("discCol"),"loose"),cb.equal(product.get("weight"),weightVar))
)
)
);
Query q = em.createQuery(cq);
return q.getResultList();

SpringBoot+Neo4J OGM update record

I am getting very weird problem when trying to update the record in database .Main Node is updating properly but Relationship not creating after deleting it.
I have Node with relationship in database i am trying to update it via this code
Role roleRecord = findByUuid(uuid);//Get Role Record
Role roleData = new Role();//Create a new role object and update values
roleData.setDescription(role.getDescription());
roleData.setUuid(roleRecord.getUuid());
roleData.setRoleName(roleRecord.getRoleName());
roleData.setLabels(updatedLabelRecord);
deleteRole(roleRecord);// Delete existing role from database
for (Labels label : dbRecord) { //Delete relationship Node
deleteLabel(label);
}
createRole(roleData);// Then Create role and Label with new Data set
This code creating Role record but not the Label Node(Which is a relationship),Relationship something like this
Role->FILTERS_ON->Label
EDIT 1-
Role is a Neo4j Entity
deleteRole is method
public void deleteRole(Role roleEntity) {
roleRepository.delete(roleEntity);
}
deleteLabel is a method
public void deleteLabel(com.nokia.nsw.uiv.uam.entities.Labels label) {
labelRepository.delete(label);
}
createRole is a method
public Role createRole(Role role) {
return roleRepository.save(role);
}
EDIT 2 -
Role Entity Class
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.Api;
#Api(
tags = "Role",
description = ""
)
#NodeEntity(label = "com.model.Role")
public class Role implements Serializable {
private static final long serialVersionUID = -8010543109475083169L;
private String roleName = null;
private String description = null;
// #Relationship(type = "HAS_ROLE", direction="INCOMING")
// private Tenant tenant;
#Relationship(type = "FILTERS_ON")
private List<Labels> labels = new ArrayList<>();
#JsonIgnore
private Long id;
#Id
#GeneratedValue(strategy = UivUuidStrategy.class)
#JsonProperty("id")
private String uuid;
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
// public Tenant getTenant() {
// return tenant;
// }
//
// public void setTenant(Tenant tenant) {
// this.tenant = tenant;
// }
public List<Labels> getLabels() {
return labels;
}
public void setLabels(List<Labels> labels) {
this.labels = labels;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Label Entity class
import java.io.Serializable;
import java.util.Map;
import java.util.Objects;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Properties;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
#NodeEntity(label = "com.model.role.Filter")
public class Labels implements Serializable {
private static final long serialVersionUID = 1L;
private String labelName;
#Properties
private Map<String, String> match;
private String access;
#JsonIgnore
private Long id;
#Id
#GeneratedValue(strategy = UivUuidStrategy.class)
#JsonProperty("id")
private String uuid;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public Map<String, String> getMatch() {
return match;
}
public void setMatch(Map<String, String> match) {
this.match = match;
}
public String getLabelName() {
return labelName;
}
public void setLabelName(String labelName) {
this.labelName = labelName;
}
public String getAccess() {
return access;
}
public void setAccess(String access) {
this.access = access;
}
#Override
public String toString() {
return "labelName : " + this.labelName;
}
#Override
public boolean equals(Object obj) {
return (obj instanceof Labels) && this.labelName.equals(((Labels) obj).getLabelName());
}
#Override
public int hashCode() {
return Objects.hash(labelName);
}
}

Spring JPARepository Update a field

I have a simple Model in Java called Member with fields - ID (Primary Key), Name (String), Position (String)
I want to expose an POST endpoint to update fields of a member. This method can accept payload like this
{ "id":1,"name":"Prateek"}
or
{ "id":1,"position":"Head of HR"}
and based on the payload received, I update only that particular field. How can I achieve that with JPARepository?
My repository interface is basic -
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository("memberRepository")
public interface MemberRepository extends JpaRepository<Member, Integer>{
}
My Member model -
#Entity
#Table(name="members")
public class Member {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="member_id")
private Integer id;
#Column(name="member_name")
#NotNull
private String name;
#Column(name="member_joining_date")
#NotNull
private Date joiningDate = new Date();
#Enumerated(EnumType.STRING)
#Column(name="member_type",columnDefinition="varchar(255) default 'ORDINARY_MEMBER'")
private MemberType memberType = MemberType.ORDINARY_MEMBER;
public Member(Integer id, String name, Date joiningDate) {
super();
this.id = id;
this.name = name;
this.joiningDate = joiningDate;
this.memberType = MemberType.ORDINARY_MEMBER;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getJoiningDate() {
return joiningDate;
}
public void setJoiningDate(Date joiningDate) {
this.joiningDate = joiningDate;
}
public MemberType getMemberType() {
return memberType;
}
public void setMemberType(MemberType memberType) {
this.memberType = memberType;
}
public Member(String name) {
this.memberType = MemberType.ORDINARY_MEMBER;
this.joiningDate = new Date();
this.name = name;
}
public Member() {
}
}
Something like this should do the trick
public class MemberService {
#Autowired
MemberRepository memberRepository;
public Member updateMember(Member memberFromRest) {
Member memberFromDb = memberRepository.findById(memberFromRest.getid());
//check if memberFromRest has name or position and update that to memberFromDb
memberRepository.save(memberFromDb);
}
}

Stop hibernate from firing update query on #ManyToOne entities

I have two entities ProductCartItem and Product. A product in my scenario is more of a master record that is never gonna change. Below is the mapping.
#Entity
#DiscriminatorValue(value = "PRODUCT")
public class ProductCartItem extends CartItem {
#ManyToOne(optional = false)
#JoinColumn(name = "product_id", referencedColumnName = "id")
private Product product;
#OneToMany(cascade = CascadeType.REMOVE, mappedBy = "parentProductCartItem",orphanRemoval = true)
#JsonManagedReference
Set<AccessoryCartItem> associatedAccessories = new HashSet<>();
#Column(name="property")
#Type(type = "ProductItemPropertyUserType")
private ProductItemProperty productItemProperty;
#OneToOne
#JoinColumn(name="project_id",referencedColumnName = "id")
private Project project;
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public Set<AccessoryCartItem> getAssociatedAccessories() {
return associatedAccessories;
}
public void setAssociatedAccessories(Set<AccessoryCartItem> associatedAccessories) {
this.associatedAccessories = associatedAccessories;
}
public void addAccessory(AccessoryCartItem accessoryCartItem) {
this.getAssociatedAccessories().add(accessoryCartItem);
}
public void removeAccessory(AccessoryCartItem accessoryCartItem) {
this.getAssociatedAccessories().remove(accessoryCartItem);
}
public ProductItemProperty getProductItemProperty() {
return productItemProperty;
}
public void setProductItemProperty(ProductItemProperty productItemProperty) {
this.productItemProperty = productItemProperty;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
}
And here is the Product entity.
#Entity
public class Product extends BaseEntity {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "title")
private String title;
#Column(name = "subtitle")
private String subtitle;
#Column(name = "description")
private String description;
#Column(name = "type_name")
private String typeName;
#Column(name = "price")
private Float price;
#Column(name = "image_list")
#Type(type = "MyImageListUserType")
private MyImageList imageList;
#Column(name = "pricing_property")
#Type(type = "PricingProperty")
private Map<String,SizePriceDTO> pricingProperty;
#JoinColumn(name = "product_type")
#ManyToOne
private ProductType productType;
private String orientation;
private Short groupId;
#Column(name = "display_order")
private Short displayOrder;
#Column(name = "base_quantity")
private int baseQuantity;
#Transient
private List<AccessoryDTO> configuredAccessoryDTOList;
public Product(){
}
public int getBaseQuantity() {
return baseQuantity;
}
public void setBaseQuantity(int baseQuantity) {
this.baseQuantity = baseQuantity;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSubtitle() {
return subtitle;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public MyImageList getImageList() {
return imageList;
}
public void setImageList(MyImageList imageList) {
this.imageList = imageList;
}
public ProductType getProductType() {
return productType;
}
public void setProductType(ProductType productType) {
this.productType = productType;
}
public String getOrientation() {
return orientation;
}
public void setOrientation(String orientation) {
this.orientation = orientation;
}
public Short getGroupId() {
return groupId;
}
public void setGroupId(Short groupId) {
this.groupId = groupId;
}
public Short getDisplayOrder() {
return displayOrder;
}
public void setDisplayOrder(Short displayOrder) {
this.displayOrder = displayOrder;
}
public List<AccessoryDTO> getConfiguredAccessoryDTOList() {
return configuredAccessoryDTOList;
}
public void setConfiguredAccessoryDTOList(List<AccessoryDTO> configuredAccessoryDTOList) {
this.configuredAccessoryDTOList = configuredAccessoryDTOList;
}
public Map<String, SizePriceDTO> getPricingProperty() {
return pricingProperty;
}
public void setPricingProperty(Map<String,SizePriceDTO> pricingProperty) {
this.pricingProperty = pricingProperty;
}
}
Now when I create a new ProductCartItem I associate an already existing Product with it. When I save the productcartitem hibernate for some reasons is firing an update query on the product table too. I have already tried setting the relationship as updatable= false but to no avail. Below is the code for the service.
private ShoppingCart addProductToCartHelper(ProductCartItemDTO productCartItemDTO) throws ShoppingException{
ShoppingCart shoppingCart;
ProductCartItem productCartItem;
Product product = productService.getProductById(productCartItemDTO.getProductDTO().getId().intValue());
if (null == product) {
throw new ShoppingException();
}
Customer currentCustomer = CanveraWebUtil.getCurrentCustomer();
GuestUser guestUser = guestUserService.loadGuestUserByUUID(CanveraWebUtil.getCurrentGuestUserIdentifier());
shoppingCart = fetchShoppingCartForCustomerOrGuestUser();
if (null == shoppingCart) {
if (null != currentCustomer) {
shoppingCart = new ShoppingCart(currentCustomer);
} else {
shoppingCart = new ShoppingCart(guestUser);
}
shoppingCart.setShoppingBagStatus(ShoppingBagStatus.DRAFT);
}
Long productCartItemDTOId = productCartItemDTO.getId();
// we will not update the associated accessories as in our case these never comes from our UI.
if (null == productCartItemDTOId) {
modifyNumberOfPages(productCartItemDTO,product);
productCartItem = new ProductCartItem();
productCartItem.setProductItemProperty(productCartItemDTO.getProductItemProperty());
productCartItem.setQuantity(productCartItemDTO.getQuantity());
productCartItem.setProduct(product);
productCartItem.setPrice(productCartItemDTO.getPrice());
productCartItem.setGiftWrap(shoppingCart.getIsGiftWrap());
//associating project
productCartItem.setProject(productCartItemDTO.getProject());
shoppingCart.addCartItem(productCartItem);
productCartItem.setShoppingCart(shoppingCart);
} else {
for (CartItem cartItem : shoppingCart.getCartItems()) {
if (null != cartItem.getId() && cartItem.getId().equals(productCartItemDTOId)) {
productCartItem = (ProductCartItem) cartItem;
productCartItem.setProductItemProperty(productCartItemDTO.getProductItemProperty());
productCartItem.setPrice(productCartItemDTO.getPrice());
productCartItem.setQuantity(productCartItemDTO.getQuantity());
}
}
}
shoppingCart = shoppingCartRepository.save(shoppingCart);
return shoppingCart;
}
Can anybody point me in the right direction ? At any point of time I do not alter any property of the product object.

Repeated column in mapping for entity: Shipper column: SHIPPER_ID (should be mapped with insert="false"

I have been going around in circles with this error and not sure why I am getting this.
Here is the mapping of Shipper class
#Entity
#Table(schema="SALONBOOKS",name="SHIPPER")
#AttributeOverride(name="id", column=#Column(name="SHIPPER_ID"))
public class Shipper extends SalonObject {
private static final long serialVersionUID = 1L;
private ShipperType name;//ShipperType.WALKIN;
#Column(name="SHIPPER_NAME")
#Enumerated(EnumType.STRING)
public ShipperType getName() {
return name;
}
public void setName(ShipperType name) {
this.name = name;
}
#Override
public Long getId(){
return id;
}
}
Here is Order class which references Shipper
#Entity
#Table(schema="SALONBOOKS",name="ORDER")
#AttributeOverride(name="id", column=#Column(name="ORDER_ID"))
public class Order extends SalonObject {
private static final long serialVersionUID = 1L;
private BigDecimal total= new BigDecimal(0.0);
private int numOfItems=0;
private BigDecimal tax= new BigDecimal(0.0);;
private String currency="USD";
private BigDecimal subTotal= new BigDecimal(0.0);
private PaymentMethod paymentMethod;
private Shipper shipper;
private OrderStatusType status;
private Appointment appointment ;
private Person person;
#Column(name="TOTAL")
public BigDecimal getTotal() {
return total;
}
public void setTotal(BigDecimal total) {
this.total = total;
}
#Column(name="NUM_OF_ITEMS")
public int getNumOfItems() {
return numOfItems;
}
public void setNumOfItems(int numOfItems) {
this.numOfItems = numOfItems;
}
#Column(name="TAX")
public BigDecimal getTax() {
return tax;
}
public void setTax(BigDecimal tax) {
this.tax = tax;
}
#Column(name="CURRENCY")
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
#Column(name="SUBTOTAL")
public BigDecimal getSubTotal() {
return subTotal;
}
public void setSubTotal(BigDecimal subTotal) {
this.subTotal = subTotal;
}
#ManyToOne
#JoinColumn(name="PAYMENT_METHOD_ID", insertable=false,updatable=false)
public PaymentMethod getPaymentMethod() {
return paymentMethod;
}
public void setPaymentMethod(PaymentMethod paymentMethod) {
this.paymentMethod = paymentMethod;
}
#ManyToOne
#JoinColumn(name="SHIPPER_ID", insertable=false,updatable=false)
public Shipper getShipper() {
return shipper;
}
public void setShipper(Shipper shipVia) {
this.shipper = shipVia;
}
#Column(name="STATUS")
#Enumerated(EnumType.STRING)
public OrderStatusType getStatus() {
return status;
}
public void setStatus(OrderStatusType status) {
this.status = status;
}
#ManyToOne
#JoinColumn(name="APPOINTMENT_ID", insertable=false,updatable=false)
public Appointment getAppointment() {
return appointment;
}
public void setAppointment(Appointment appointment) {
this.appointment = appointment;
}
#ManyToOne
#JoinColumn(name="PERSON_ID", insertable=false,updatable=false)
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
#Override
public Long getId(){
return id;
}
}
each of these extends:
#MappedSuperclass
public abstract class SalonObject implements Entity, Serializable {
private static final long serialVersionUID = 1L;
protected Long id;
protected DateTime createDate;
protected DateTime updateDate;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof SalonObject
&& obj !=null){
return ObjectUtils.equals(this.id, ((SalonObject) obj).getId()) ;
}
return false;
}
#Column(name="CREATE_DATE")
public DateTime getCreateDate() {
return createDate;
}
public void setCreateDate(DateTime dateTime) {
this.createDate = dateTime;
}
#Column(name="UPDATE_DATE")
public DateTime getUpdateDate() {
return updateDate;
}
public void setUpdateDate(DateTime updateDate) {
this.updateDate = updateDate;
}
}
The stackTrace is ::
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: salonbooks.model.Shipper column: SHIPPER_ID (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:709)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:731)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:753)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:506)
at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1358)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1849)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:343)
at salonbooks.core.HibernateConfiguration.sessionFactory(HibernateConfiguration.java:109)
removing the following method from Shipper and from Order worked to resolve this error
#Override
public Long getId(){
return id;
}
Because you are using property access, by overriding the base method (containing the mapping configuration) you will replace your base method mapping configuration with no config at all.
Using field access wouldn't have caused this issue, but the override would have been useless anyway. The id field should have private access too, so this method wouldn't compile if you change the access modifier.

Resources