Results 1 to 8 of 8
  1. #1
    willemjav is offline Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,139
    Rep Power
    13

    Default problem with deleting entry at a common table with extra column

    The declaration of the common table of Product and Order (ProductOrder)
    with extra column(s) (only the relevant fields)

    at Product

    Java Code:
    @OneToMany(fetch=FetchType.LAZY, mappedBy="product")
    	private List<ProductOrder> productOrders;
    at Order

    Java Code:
    @OneToMany(fetch=FetchType.LAZY, mappedBy="order")
    	private List<ProductOrder> productOrders;

    at ProductOrder

    Java Code:
    private ProductOrderId id;
    
    	@ManyToOne(fetch=FetchType.LAZY)
        @JoinColumn(name="order_id", nullable=false, insertable=false, updatable=false)
    	private Order order;
    
    	@ManyToOne(fetch=FetchType.LAZY)
        @JoinColumn(name="product_id", nullable=false, insertable=false, updatable=false)
    	private Product product;
    
        public ProductOrder() {
        }
    
        public ProductOrder(Integer productId, Integer orderId) {
    		this.id = new ProductOrderId(productId, orderId);
        }
    at ProductOrderId

    Java Code:
    	@Column(name="product_id", nullable=false)
    	private Integer productId;
    
    
        @Column(name="order_id", nullable=false)
    	private Integer orderId;
    
        public ProductOrderId() {
        }
    
        public ProductOrderId(Integer productId, Integer orderId) {
    		this.productId = productId;
    		this.orderId = orderId;
        }
    The deleting dao

    Java Code:
    	@Override
        	public void deleteById(ProductOrderId id) {
    		System.out.println("at product oder dao id: " + id);
        		super.deleteById(id);
        	}
    
    @Override
        public void delete(ProductOrder productOrder) {
        	super.delete( productOrder);
        }
    
    // creating a product order
    ProductOrder po = new ProductOrder();
    
    // create an order (o) and a Product (p) with several values set, than 
    
    po.setOrder(o);
    po.setProduct(p);
    
    // create the entry at ProductOrder like this:
    
    po.setId(new ProductOrderId(po.getProduct().getId(),po.getOrder().getId()));			
    getProductOrderDao().insert(po);
    
    //deleting the ProductOrder
    //ProductOrder po = new ProductOrder();
    //8 is an existing product id and 59 is an existing order if!
    //po.setId(new ProductOrderId(8, 59));
    //getProductOrderDao().delete(po);
    getProductOrderDao().deleteById(new ProductOrderId(8, 59));

    But I get an error when deleting:
    at product oder dao id: com.myfirm.shoponline.model.ProductOrderId@70eecdc 2
    generic dao deleteById: com.myfirm.shoponline.model.ProductOrderId@70eecdc 2
    finally is txn delete open: : true
    Exception in thread "main" java.lang.IllegalArgumentException: Unknown entity: com.myfirm.shoponline.model.ProductOrderId
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.re move(AbstractEntityManagerImpl.java:1217)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.orm.jpa.ExtendedEntityManagerC reator$ExtendedEntityManagerInvocationHandler.invo ke(ExtendedEntityManagerCreator.java:344)
    at com.sun.proxy.$Proxy21.remove(Unknown Source)
    at com.myfirm.shoponline.generic.GenericDaoImpl.delet eById(GenericDaoImpl.java:131)
    at com.myfirm.shoponline.dao.impl.ProductOrderDaoImpl .deleteById(ProductOrderDaoImpl.java:38)
    at com.myfirm.shoponline.Tester.deleteProductOrder(Te ster.java:148)
    at com.myfirm.shoponline.Tester.main(Tester.java:200)
    Caused by: org.hibernate.MappingException: Unknown entity: com.myfirm.shoponline.model.ProductOrderId



    Java Code:
    @Component
    public abstract class GenericDaoImpl<T, T2> implements GenericDao<T, T2> {
        
        @Autowired
    	private ConnectionManager connectionManager;
        private Class<T> type;
        private Class<T2> type2;
    
        public GenericDaoImpl() {
            Type t = getClass().getGenericSuperclass();
            ParameterizedType pt = (ParameterizedType) t;
            type = (Class) pt.getActualTypeArguments()[0];
            type2 = (Class) pt.getActualTypeArguments()[0];
            System.out.println(">>>getClass()// " + getClass().getName() + " //getGenericSuperclass()// " + t + " //ParameterizedType// " + pt + " //generic dao type// " + type +  " //generic dao type2// " + type2);
        }
    
        //@Override
        public List<T> getAll() {
        	System.out.println("generic dao all ");
        	return ConnectionManager.getEntityManager().createQuery("from " + type.getSimpleName(), type).getResultList(); 
        }
        
        //@Override
        public T findById(final Integer id) {
        	System.out.println("generic dao findById: " + id);
        	return (T) ConnectionManager.getEntityManager().find(type, id);
        }
        
        //@Override
        public T find(final T t) {
        	return (T) ConnectionManager.getEntityManager().find(type, t);
        }
        
        //@Override
        public T insert(final T t) {
        	EntityManager em = null;
        	EntityTransaction txn = null;
        	try{
    	    	em = ConnectionManager.getEntityManager();
        		txn = em.getTransaction();
        		txn.begin();
        		System.out.println("generic dao insert: " + t);
        		em.persist(t);
    	    	txn.commit();
        	}
        	catch (HibernateException e) {
        		System.out.println("roll back create: " + e);
        		txn.rollback();
        		handleException(e);
        	} 
        	finally {
        		//em.close();
        		//System.out.println("finally is txn create open: : " + txn.isActive());
        	}
        	return t;
        }
        
        //@Override
        public T update(final T t) {
        	EntityManager em = null;
        	EntityTransaction txn = null;
        	try{
    	    	em = ConnectionManager.getEntityManager();
        		txn = em.getTransaction();
        		txn.begin();
        		System.out.println("generic dao update: " + t);
        		em.merge(t);
    	    	txn.commit();
        	}
        	catch (HibernateException e) {
        		System.out.println("roll back update: " + e);
        		txn.rollback();
        		handleException(e);
        	} 
        	finally {
        		em.close();
        		System.out.println("finally is txn update open: : " + txn.isActive());
        	}
        	return t;
        }
    
        //@Override
        //@Transactional
        public void delete(final T t) {
        	EntityManager em = null;
        	EntityTransaction txn = null;
        	try{
        		em = ConnectionManager.getEntityManager();
        		txn = em.getTransaction();
        		txn.begin();
    	    	System.out.println("generic dao delete: " + t);
    	    	em.remove(t);
    	    	txn.commit();
        	}
        	catch (HibernateException e) {
        		System.out.println("roll back delete: " + e);
        		txn.rollback();
        		handleException(e);
        	} 
        	finally {
        		em.close();
        		System.out.println("finally is txn delete open: : " + txn.isActive());
        	}
        }
        
        //@Override
        //@Transactional
        public void deleteById(final T2 t) {
        	EntityManager em = null;
        	EntityTransaction txn = null;
        	try{
        		em = ConnectionManager.getEntityManager();
        		txn = em.getTransaction();
        		txn.begin();
    	    	System.out.println("generic dao deleteById: " + t);
    	    	em.remove(t);
    	    	txn.commit();
        	}
        	catch (HibernateException e) {
        		System.out.println("roll back deleteById: " + e);
        		txn.rollback();
        		handleException(e);
        	} 
        	finally {
        		em.close();
        		System.out.println("finally is txn delete open: : " + txn.isActive());
        	}
        }
        
        
        
        private void handleException(HibernateException e) { //throws DataAccessLayerException {
        	 SQLException cause = (SQLException) e.getCause();
    		 System.out.println(cause.getMessage());
        	 //throw new DataAccessLayerException(e);
        }
    }
    Last edited by willemjav; 07-04-2015 at 02:53 PM.

  2. #2
    willemjav is offline Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,139
    Rep Power
    13

    Default Re: problem with deleting entry at a common table with extra column

    The problem might as well be at the generic dao class, see type2 e.g.

  3. #3
    willemjav is offline Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,139
    Rep Power
    13

    Default Re: problem with deleting entry at a common table with extra column

    There is a problem with the embedded annotation, I believe.
    Could it be the raison that hibernate is not finding that entity?

    Java Code:
    import java.io.Serializable;
    import javax.persistence.Column;
    import javax.persistence.Embeddable;
    import javax.persistence.Entity;
    
    
    
    @Embeddable
    public class ProductOrderId implements Serializable { //extends GenericObject {
    
    	private static final long serialVersionUID = 1L;
    
        @Column(name="product_id", nullable=false)
    	private Integer productId;
    
        @Column(name="order_id", nullable=false)
    	private Integer orderId;
    
        public ProductOrderId() {
        }
    
        public ProductOrderId(Integer productId, Integer orderId) {
    		this.productId = productId;
    		this.orderId = orderId;
        }
    
    	public Integer getProductId() {
    		return this.productId;
    	}
    
    	public void setProductId(Integer productId) {
    		this.productId = productId;
    	}
    
    	public Integer getOrderId() {
    		return this.orderId;
    	}
    
    	public void setOrderId(Integer orderId) {
    		this.orderId = orderId;
    	}
    
    	@Override
    	public String toString() {
    		return "ProductOrderId [productId=" + productId + ", orderId="
    				+ orderId + "]";
    	}
    }
    the entity works together with:

    Java Code:
    import java.math.BigDecimal;
    import javax.persistence.Column;
    import javax.persistence.EmbeddedId;
    import javax.persistence.Entity;
    import javax.persistence.EntityListeners;
    import javax.persistence.FetchType;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    
    @Entity
    @EntityListeners({
    	//SysListener.class
    })
    @Table(name="product_order", catalog="shoponline")
    public class ProductOrder { //extends GenericObject {
    
    	private static final long serialVersionUID = 1L;
    	
    	@EmbeddedId    
    	private ProductOrderId id;
    
    	@ManyToOne(fetch=FetchType.LAZY)
        @JoinColumn(name="order_id", nullable=false, insertable=false, updatable=false)
    	private Order order;
    
    	@ManyToOne(fetch=FetchType.LAZY)
        @JoinColumn(name="product_id", nullable=false, insertable=false, updatable=false)
    	private Product product;
    
        @Column(name="list_price", precision=9)
    	private BigDecimal listPrice;
    
        @Column(name="product_quantity")
    	private Integer productQuantity;
    
        public ProductOrder() {
        }
    
        public ProductOrder(Integer productId, Integer orderId) {
    		this.id = new ProductOrderId(productId, orderId);
        }
    
    	public ProductOrderId getId() {
    		return this.id;
    	}
    
    	public void setId(ProductOrderId id) {
    		this.id = id;
    	}
    
    	public Order getOrder() {
    		return this.order;
    	}
    
    	public void setOrder(Order order) {
    		this.order = order;
    	}
    
    	public Product getProduct() {
    		return this.product;
    	}
    
    	public void setProduct(Product product) {
    		this.product = product;
    	}
    
    	public BigDecimal getListPrice() {
    		return this.listPrice;
    	}
    
    	public void setListPrice(BigDecimal listPrice) {
    		this.listPrice = listPrice;
    	}
    
    	public Integer getProductQuantity() {
    		return this.productQuantity;
    	}
    
    	public void setProductQuantity(Integer productQuantity) {
    		this.productQuantity = productQuantity;
    	}
    
    	@Override
    	public String toString() {
    		return "ProductOrder [id=" + id + ", order=" + null + ", product="
    				+ null + ", listPrice=" + listPrice + ", productQuantity="
    				+ productQuantity + "]";
    	}
    }
    resulting into the error:

    Exception in thread "main" java.lang.IllegalArgumentException: Unknown entity: com.myfirm.shoponline.model.ProductOrderId
    Last edited by willemjav; 07-05-2015 at 05:53 PM.

  4. #4
    gimbal2 is offline Just a guy
    Join Date
    Jun 2013
    Location
    Netherlands
    Posts
    5,114
    Rep Power
    12

    Default Re: problem with deleting entry at a common table with extra column

    Let me check the flow:

    - you have a class representing an embedded primary key
    - you pass that object to deleteById
    - deleteById calls remove() which is designed to remove an entity
    - but you're not passing an entity to be deleted, you pass the non-entity embedded primary key
    - you correctly get an exception

    I don't see a problem, working as designed.
    "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis

  5. #5
    willemjav is offline Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,139
    Rep Power
    13

    Default Re: problem with deleting entry at a common table with extra column

    Yep you are right, but I had to correct a general misunderstanding of how to present an entity!
    I thought that when you create an object (using new) and put the right id to that object, that object could present the one to delete at the DB, right? No, wrong!

    eg:
    -there is an existing entry at ProductOrder table with orderId=x and productId=y
    -then create and object like this ProductOrderId poi = new ProductOrderId(y, x));
    -and next getProductOrderDao().deleteById(poi);

    but this results into the error: Exception in thread "main" java.lang.IllegalArgumentException: Unknown entity:

    So what I SHOULD BE DOING is find the entry of the table (as an object) by id and delete THAT VERY ONE, right?

    Now I got into yet another confusing fact which is: that x/y entry of the product_order table has no "traditional integer id".
    So I needed to create a new method that finds a ProductOrder object by ProductOrderId id like this:

    Java Code:
    @Component(value = "ProductOrderDao")
    public class ProductOrderDaoImpl extends GenericDaoImpl<ProductOrder, ProductOrderId> implements ProductOrderDao {
    	
    	@Override
    	public ProductOrder search(ProductOrderId id) {
    		return super.search(id);
    	}
    and implement that on at the generic dao class like this:

    Java Code:
    @Component
    public abstract class GenericDaoImpl<T, T2> implements GenericDao<T, T2> {
        
        @Autowired
    	private ConnectionManager connectionManager;
        private Class<T> type;
        private Class<T2> type2;
    
        public GenericDaoImpl() {
            Type t = getClass().getGenericSuperclass();
            ParameterizedType pt = (ParameterizedType) t;
            type = (Class) pt.getActualTypeArguments()[0];
            type2 = (Class) pt.getActualTypeArguments()[0];
            
            System.out.println("generic dao getClass()// " + getClass().getName() + " //getGenericSuperclass()// " + t + " //ParameterizedType// " + pt + " //generic dao type// " + type);
        }
    
        //@Override
        public List<T> getAll() {
        	System.out.println("generic dao all ");
        	return ConnectionManager.getEntityManager().createQuery("from " + type.getSimpleName(), type).getResultList(); 
        }
        
        //@Override
        public T findById(final Integer id) {
        	System.out.println("generic dao findById: " + id);
        	return (T) ConnectionManager.getEntityManager().find(type, id);
        }
        
        public T search(final T2 t) {
        	System.out.println("generic dao search: " + t);
        	return (T) ConnectionManager.getEntityManager().find(type, t);
        }
    finally that resulted in a correct deleting of the product_order entry.... haleeeluoooaaa!

  6. #6
    willemjav is offline Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,139
    Rep Power
    13

    Default Re: problem with deleting entry at a common table with extra column

    btw here is the actual deleting method a the dao imll of productorder:
    Java Code:
    @Override
        public void delete(ProductOrder productOrder) {
    		super.delete(search(productOrder.getId()));
        }

  7. #7
    gimbal2 is offline Just a guy
    Join Date
    Jun 2013
    Location
    Netherlands
    Posts
    5,114
    Rep Power
    12

    Default Re: problem with deleting entry at a common table with extra column

    That's one way that ultimately results in two queries to delete a single record (fetch, delete). You can do it in one go by doing an actual delete query yourself rather than using remove().

    JPA: composite key and deleting records problem (Object Relational Mapping forum at JavaRanch)

    I actually -prefer- the fetch-remove way you have used now. The reason is that this makes a harder business rule out of deleting an existing record. If you do a manual delete query you'd have to check the number of records updated to see if anything happened or not, and manually trip an error if nothing was deleted (or ignore it depending on the situation). If you fetch first and the record does not exist that will auto-magically result in an exception (NoResultException) without you needing to do anything at all.

    Usually when you want to remove something it should still exist and so when you remove something which has already been removed that is a sign of system instability that needs a correction of the system architecture; as an example that is an indication that optimistic locking might be needed in multiuser applications. In a web application it might be an indicator that form-resubmission is not being handled properly. Etc. etc.
    "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis

  8. #8
    willemjav is offline Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,139
    Rep Power
    13

    Default Re: problem with deleting entry at a common table with extra column

    your comment is crystal clear, thanks

Similar Threads

  1. “Extra Column” in TableView
    By pugazhendhiobs in forum JavaFX
    Replies: 2
    Last Post: 03-24-2012, 07:22 PM
  2. Replies: 0
    Last Post: 11-02-2010, 12:23 PM
  3. Replies: 1
    Last Post: 07-06-2010, 04:50 PM
  4. Vector/Table Deleting Row Problem.
    By ocean in forum New To Java
    Replies: 8
    Last Post: 12-09-2009, 06:39 PM
  5. Joining two 2D Arrays over a common column
    By Sknight126 in forum Advanced Java
    Replies: 0
    Last Post: 11-02-2007, 11:29 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •