PropertyAccessException:调用setter时发生IllegalArgumentException

时间:2014-11-28 08:54:01

标签: java mysql spring hibernate jpa

我正在使用带有JPA / Hibernate 4的Spring 3.我在尝试持久化“Product”实体时遇到了IllegalArgumentException。 我在Product和Category之间有一对多的关系,并且有一个复合键ProductId类只有产品和类别的PK。我使用@IdClass注释,因为两个PK都是由DB(MySql)自动生成的。 我的下面的代码将更好地解释它。

我的SQL脚本:

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;

我的模型类: Product,Category和ProductId复合键类。

@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;
}

}

我的ProductService类保存方法。

@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;
}

有人可以帮我解决这个问题吗?我引用了一些博客和Java Persistence wikibooks,映射似乎没问题。我不明白为什么会发生这种异常。

修改

哦,我忘了添加堆栈跟踪。在这里。

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)

编辑2:从ProductId类中删除了@IdClass注释。

2 个答案:

答案 0 :(得分:0)

我认为你不需要在ProductId类上使用@IdClass。它仅适用于您使用此复合ID的实体。而这个特殊错误是由于您尝试使用整数但必须使用ProductId类的事实引起的。试试这种方式

@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
}

在ProductId类中:

private Integer prodId;
private Category category;

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

getters&setters

然后将其设置为:

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

并试试这个:

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

你错过的主要原因可能是Produt和IdClass ProductId的setter有相似的名字。

如果使用IdClass,你不需要任何@GeneratedValue注释。

答案 1 :(得分:0)

如果您想使用@IdClass,那么属性名称&amp; ProductId类和Product实体中的类型必须匹配。

在您宣布的Product.java课程中: prodIdIntegercategoryCategory

但是在ProductId.java类中,您声明了: prodIdIntegercategoryInteger

你也不应该在@IdClass课程中发表ProductId声明,你必须将其删除。

尝试以下更改:

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&amp;干将     }

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;
    }

}

此更改还将解决与composite identifier cannot be null相关的问题。