0

I am using Spring 3 with JPA/Hibernate 4. I am getting an IllegalArgumentException when trying to persist a "Product" entity. I have a One to many relation between Product and Category, and there is a composite key ProductId class that has only the PKs of Product and Category. I used @IdClass annotation as both PKs are auto generated by the DB (MySql). My code below will explain it better.

My SQL script:

CREATE TABLE IF NOT EXISTS `orangeDB`.`Category` (
`catId` INT NOT NULL AUTO_INCREMENT,
`category` VARCHAR(45) NOT NULL,
`lft` INT NOT NULL,
`rgt` INT NOT NULL,
PRIMARY KEY (`catId`),
UNIQUE INDEX `categoryId_UNIQUE` (`catId` ASC))
ENGINE = InnoDB
AUTO_INCREMENT = 1795327;

CREATE TABLE IF NOT EXISTS `orangeDB`.`Product` (
`prodId` INT(9) NOT NULL AUTO_INCREMENT,
`prefix` CHAR NOT NULL,
`product` VARCHAR(45) NOT NULL,
`quantity` INT(9) NOT NULL,
`price` DOUBLE NOT NULL,
`discount` INT(9) NOT NULL,
`catId` INT NOT NULL,
PRIMARY KEY (`prodId`, `catId`),
INDEX `fk_Product_Category1_idx` (`catId` ASC),
CONSTRAINT `fk_Product_Category1`
  FOREIGN KEY (`catId`)
  REFERENCES `orangeDB`.`Category` (`catId`)
  ON DELETE CASCADE
  ON UPDATE CASCADE)
ENGINE = InnoDB
AUTO_INCREMENT = 1143713;

My Model classes: Product, Category and ProductId composite key class.

@SuppressWarnings("serial")
@Entity
@Table(name = "Category", catalog = "orangeDB")
public class Category implements java.io.Serializable {

private Integer catId;
private String category;
private int lft;
private int rgt;
private Set<Product> products = new HashSet<Product>(0);

public Category() {
}

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "catId", unique = true, nullable = false)
public Integer getCatId() {
    return this.catId;
}

public void setCatId(Integer catId) {
    this.catId = catId;
}

@Column(name = "category", nullable = false, length = 45)
public String getCategory() {
    return this.category;
}

public void setCategory(String category) {
    this.category = category;
}   

@OneToMany(fetch = FetchType.LAZY, mappedBy = "category")
public Set<Product> getProducts() {
    return this.products;
}

public void setProducts(Set<Product> products) {
    this.products = products;
}

public void addProduct(Product product) {
    this.products.add(product);
    if (product.getCategory() != this) {
        product.setCategory(this);
    }
}

// other getters and setters
}

@SuppressWarnings("serial")
@Entity
@IdClass(ProductId.class)
@Table(name = "Product", catalog = "orangeDB")
public class Product implements java.io.Serializable {

private Integer prodId;
private Category category;
private char prefix = 'P';
private String product;
private int quantity;
private double price;
private int discount;

public Product() {
}

 @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "prodId", nullable = false)
public Integer getProdId() {
    return this.prodId;
}

public void setProdId(Integer prodId) {
    this.prodId = prodId;
}

@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "catId", referencedColumnName = "catId", nullable = false, insertable = false, updatable = false)
public Category getCategory() {
    return this.category;
}

public void setCategory(Category category) {
    this.category = category;       
}   

@Column(name = "product", nullable = false, length = 45)
public String getProduct() {
    return this.product;
}

public void setProduct(String product) {
    this.product = product;
}

// other getters and setters
}

@SuppressWarnings("serial")
public class ProductId implements java.io.Serializable {

private Integer prodId;
private Integer category;

public ProductId() {
}

public ProductId(Integer prodId, Integer category) {
    this.prodId = prodId;
    this.category = category;
}


public Integer getProdId() {
    return this.prodId;
}

public void setProdId(Integer prodId) {
    this.prodId = prodId;
}


public Integer getCategory() {
    return this.category;
}

public void setCategory(Integer category) {
    this.category = category;
}

public boolean equals(Object other) {
    if ((this == other))
        return true;
    if ((other == null))
        return false;
    if (!(other instanceof ProductId))
        return false;
    ProductId castOther = (ProductId) other;

    return (this.getProdId() == castOther.getProdId())
            && (this.getCategory() == castOther.getCategory());
}

public int hashCode() {
    int result = 17;

    result = 37 * result + this.getProdId();
    result = 37 * result + this.getCategory();
    return result;
}

}

My ProductService class save method.

@Transactional
public Product save(Product product, Integer catId) {
    Category category = categoryService.findOne(catId);
            // setting a prodId manually for now, else I get a composite 
            // identifier cannot be null exception, which is also another issue for me.
    product.setProdId(1122);
    category.addProduct(product);
    if (product.getProdId() == null) {

        em.persist(product);

    } else {
        em.merge(product);
    }
    return product;
}

Could someone help me get this to work? I referred a few blogs and the Java Persistence wikibooks, and the mapping seems to be be fine. I cant understand why this exception is occurring.

EDIT

Oh, I forgot to add the stack trace. Here it is.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of model.ProductId.prodId
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:965)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

root cause

javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of model.ProductId.prodId
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1316)
org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:881)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
$Proxy32.persist(Unknown Source)
service.ProductServiceImpl.save(ProductServiceImpl.java:42)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
$Proxy35.save(Unknown Source)
controller.Admincontroller.addProduct(Admincontroller.java:276)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:919)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

root cause

org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of model.ProductId.prodId
org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:119)
org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:423)
org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:121)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:117)
org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:853)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:827)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:831)
org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:875)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
$Proxy32.persist(Unknown Source)
service.ProductServiceImpl.save(ProductServiceImpl.java:42)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
$Proxy35.save(Unknown Source)
controller.Admincontroller.addProduct(Admincontroller.java:276)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:919)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

root cause

java.lang.IllegalArgumentException: argument type mismatch
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:65)
org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:423)
org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:121)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:117)
org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:853)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:827)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:831)
org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:875)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
$Proxy32.persist(Unknown Source)
service.ProductServiceImpl.save(ProductServiceImpl.java:42)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
$Proxy35.save(Unknown Source)
controller.Admincontroller.addProduct(Admincontroller.java:276)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:919)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

EDIT 2: Removed @IdClass annotation from ProductId class.

Oh Ha Ni
  • 3
  • 1
  • 3

2 Answers2

0

I dont think you need @IdClass on class ProductId. It's required only for entity in which you are using this composite id. And this particular error is caused by the fact that you try to use integer but you have to use ProductId class. Try this way

@SuppressWarnings("serial")
@Entity
@IdClass(ProductId.class)
@Table(name = "Product", catalog = "orangeDB")
public class Product implements java.io.Serializable {    
    private Integer prodId;
    private Category category;
    private char prefix = 'P';
    private String product;
    private int quantity;
    private double price;
    private int discount;

    @Id
    @Column(name = "prodId", nullable = false)
    public Integer getProdId() {
        return this.prodId;
    }

    public void setProdIt(Integer prodId) {
        this.prodId = prodId;
    }


    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "catId", referencedColumnName = "catId", nullable = false, insertable = false, updatable = false)
    public Category getCategory() {
        return this.category;
    }

    public setProductId(ProductId productId){
        this.prodId = productId.getProdId();
        this.category = productId.getCategory();
    }

    //getter&setters
}

in ProductId class:

private Integer prodId;
private Category category;

public ProductId(Integer prodId, Category category) {
    this.prodId = prodId;
    this.category = category;
}

getters&setters

and then set it with:

Category category = new Category();
ProductId pId = new ProductId(1, category); //id, category
product.setProductId(pId);

and try this as well:

new Product(1, category); // pls add this constructor

The main reason why you missed that is probably the fact that setter from Produt and IdClass ProductId have similar names.

And in case od using IdClass you dont need any @GeneratedValue annotation.

iku
  • 1,007
  • 2
  • 10
  • 23
  • It didn't work. Still shows the same exception. I removed the @IdClass annotation from ProductId class. The setProdId() method in the Product class takes an Integer. So the compiler gives an error if I pass an instance of ProductId. So I tried changing the prodId field in Product from Integer type to ProductId type and then did as you said but it gave the same exception. – Oh Ha Ni Nov 28 '14 at 10:34
  • I think that now it should work. Look at edited version. The most important part is that ProductId should have Category in its fields as it's a part in class Product – iku Nov 28 '14 at 10:50
  • Thanks for your reply. But I think I did not understand your answer. The product.setProdId() method takes an argument of type Integer. But in your solution, you are passing pId, which is of type ProductId, into the setProdId(). The compiler gives an error. – Oh Ha Ni Nov 28 '14 at 11:25
  • Sorry I was writing it in a hurry. Now, it should be more specific. But idea is the same. In your IdClass category can't be int as it is of type Category in product and is marked as @Id. – iku Nov 28 '14 at 11:47
  • Uff...I still cant get this exception off my back. I don't know whats with this setter method of ProductId. I did exactly as you said but it still gives the same exception. Is there any way to avoid a composite key and work with only one PK? – Oh Ha Ni Nov 28 '14 at 12:14
  • There is another way - using @EmbeddedId. Look http://stackoverflow.com/questions/212350/which-annotation-should-i-use-idclass-or-embeddedid But your issue is really strange. What hibernate version do you use? – iku Nov 28 '14 at 14:48
  • Sorry for late reply, I was out of office for the weekend. Initially we had used '@EmbeddedId' but we are using '@GeneratedValue' which does not work with '@EmbeddedId'. So we changed to '@IdClass'. The mapping was generated using Hibernate Tools 4.0.0. The version of Hibernate is 4.2.1 and Spring 3.2.11. – Oh Ha Ni Dec 01 '14 at 05:27
  • It works! Thanks mate! I forgot to remove the '@GeneratedValue' annotation from the Product entity class. I pass in a null value for prodId while calling new on ProductId. And the value gets generated in the DB. :-D – Oh Ha Ni Dec 01 '14 at 05:57
0

If you want to use @IdClass then the property names & types in ProductId class and Product entity must match.

In your Product.java class you have declared: prodId as Integer and category as Category

But in ProductId.java class, you have declared: prodId as Integer and category as Integer

Also you should not have @IdClass declaration in ProductId class, you have to remove that.

Try below changes:

Product.java

@Entity
@IdClass(ProductId.class)
@Table(name = "Product")
public class Product implements java.io.Serializable {

    private Integer prodId;
    private Category category;
    private int categoryId; // Adding new property

    @Id
    @GeneratedValue
    @Column(name = "prodId", nullable = false)
    public Integer getProdId() {
        return this.prodId;
    }

    @Id
    @Column(name = "catId", insertable = false, updatable = false)
    public int getCategoryId() {
        return categoryId;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "catId", referencedColumnName = "catId", nullable = false, insertable = false, updatable = false)
    public Category getCategory() {
        return this.category;
    }

// Setters & getters }

ProductId.java

// Remove the @IdClass annoatation from here
public class ProductId implements java.io.Serializable {

    private Integer prodId;
    private Integer categoryId; // The property name should match

    public ProductId() {
    }

    public ProductId(Integer prodId, Integer categoryId) {
        this.prodId = prodId;
        this.categoryId = categoryId;
    }

    public Integer getProdId() {
        return this.prodId;
    }

    public void setProdId(Integer prodId) {
        this.prodId = prodId;
    }

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }

    public boolean equals(Object other) {
        if ((this == other))
            return true;
        if ((other == null))
            return false;
        if (!(other instanceof ProductId))
            return false;
        ProductId castOther = (ProductId) other;

        return (this.getProdId() == castOther.getProdId())
                && (this.getCategoryId() == castOther.getCategoryId());
    }

    public int hashCode() {
        int result = 17;

        result = 37 * result + this.getProdId();
        result = 37 * result + this.getCategoryId();
        return result;
    }

}

This change will also solve the issue related to composite identifier cannot be null.

Chaitanya
  • 15,403
  • 35
  • 96
  • 137
  • Didn't work. But I think this removed the "composite identifier cannot be null" exception. I checked by commenting out the statement where I set the prodId as 1122 and it didn't show that identifier exception. But the IllegalArgumentException on the setter of ProductId still occurs. – Oh Ha Ni Nov 28 '14 at 10:57
  • @OhHaNi, can you post complete stacktrace of error, your question do not have complete error message. – Chaitanya Nov 28 '14 at 11:07
  • I have edited my question and added the complete stack trace. You can ask any more details you want. – Oh Ha Ni Nov 28 '14 at 11:18