Ошибка org.hibernate.property. basicpropertyaccessor - illegalargumentexception
Я использую XML-отображение. Я попытался создать связь "многие ко многим" между счетом-фактурой и продуктом (счет-фактура может содержать много продуктов, а продукт может принадлежать многим счетам-фактурам). Мой подход состоял в том, чтобы создать ассоциацию под названием "InvoiceLine", которая будет содержать один продукт, его количество и общую сумму, и эта InvoiceLine будет принадлежать одному счету-фактуре.
- Счет-фактура имеет много линий счетов-фактур
- Строка счета-фактуры имеет много продуктов и имеет атрибут, который является идентификатором счета-фактуры, соответствующим счету-фактуре
В поисках способа сделать это сопоставление я пришел к выводу, что вы не можете сделать ассоциацию "многие ко многим" с дополнительным столбцом и что мне нужно сделать 2 ассоциации "один ко многим", чтобы заменить эту ассоциацию "многие ко многим".
Что я уже пробовал:
Это то, что я пытался, но я продолжаю получать ошибку:
19359 [http-nio-8088-exec-3] ERROR org.hibernate.property.BasicPropertyAccessor - IllegalArgumentException in class: model.InvoiceLine, getter method of property: Product org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of model.InvoiceLine.Product at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:195) at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:87) at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:93) at org.hibernate.tuple.component.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:109) at org.hibernate.type.serComponentType.getPropertyValues(ComponentType.java:376) at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:207) at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:126) at org.hibernate.engine.EntityKey.<init>(EntityKey.java:70) at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:184) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210) at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195) at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93) at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:562) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:550) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:546) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:342) at com.sun.proxy.$Proxy5.save(Unknown Source) at dao.GenericDaoHibernateImpl.add(GenericDaoHibernateImpl.java:49) at dao.InvoiceLineDaoImpl.ajouter(InvoiceLineDaoImpl.java:12) at services.InvoiceLineServiceImpl.ajouter(InvoiceLineServiceImpl.java:25) at controller.InvoiceLineServlet.doPost(InvoiceLineServlet.java:123) at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1100) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:687) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:169) ... 50 more
Вот мои классы отображения, сущность ассоциации и сервлет.
**InvoiceLine.hbm.xml:**
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="model.InvoiceLine" table="INVOICE_LINE"> <composite-id name="id" class="model.InvoiceLine"> <key-many-to-one name="Product" entity-name="model.Product" column="CODE_PRODUCT" /> <key-many-to-one name="Invoice" entity-name="model.Invoice" column="ID_INVOICE"/> </composite-id> <property name="qte" column="quantity" /> <property name="total" column="TOTAL" /> </class> </hibernate-mapping>
**Product.hbm.xml:**
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="model.Product" table="PRODUCT"> <meta attribute="class-description"> </meta> <id name="codeProduct" column="CODE_PRODUCT"> <generator class="native"/> </id> <property name="name" column="NAME" /> <property name="description" column="DESCRIPTION" /> <property name="price" column="PRICE" /> <property name="quantityStock" column="QUANTITY_STOCK" /> <many-to-one name="category" class="model.category" fetch="select" update="true"> <column name="CODE_CATEGORY" not-null="true" /> </many-to-one> <set name="invoiceline" table="INVOICE_LINE" inverse="true" fetch="select" cascade="all"> <key> <column name="CODE_PRODUCT" not-null="true" /> </key> <one-to-many class="model.InvoiceLine" /> </set> </class> </hibernate-mapping>
**Invoice.hbm.xml:**
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="model.Invoice" table="INVOICE"> <meta attribute="class-description"> </meta> <id name="id" column="ID_INVOICE"> <generator class="native"/> </id> <property name="date" column="DATE" /> <property name="total" column="TOTAL" /> <many-to-one name="client" class="model.Client" fetch="select" update="true"> <column name="ID_CLIENT" not-null="true" /> </many-to-one> <set name="InvoiceLine" table="INVOICE_LINE" inverse="true" fetch="select" cascade="all"> <key> <column name="ID_INVOICE" not-null="true" /> </key> <one-to-many class="model.InvoiceLine" /> </set> </class> </hibernate-mapping>
А это и есть * * сервлет**
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if ((request.getParameter("addInvoiceLine")) != null) { RequestDispatcher dispatcher = request.getRequestDispatcher("/View/AddInvoiceLine.jsp"); dispatcher.forward(request, response); //get the InvoiceId from a select list String[] invoice = request.getParameterValues("invoice"); int codeInvoice = Integer.parseInt(invoice[0]); //get the ProductId from a select list String[] product= request.getParameterValues("product"); int codeProd = Integer.parseInt(product[0]); //get the quantity from a textField and convert it to integer String stringQuantity = request.getParameter("quantity"); int quantity= Integer.parseInt(stringQuantity); InvoiceServiceImpl InvoiceService = new InvoiceServiceImpl(); Invoice invoice= invoiceService.return(codeInvoice); ProductServiceImpl productService = new ProductServiceImpl(); Product product = productService.return(codeProd); InvoiceLineServiceImpl invoiceLineServiceImpl = new InvoiceLineServiceImpl(); InvoiceLine invoiceLine= new InvoiceLine(quantity); invoiceLine.setProduct(product); invoiceLine.setInvoice(invoice); invoiceLineServiceImpl.add(invoiceLine);
Строка, которая выдает ошибку, такова:
invoiceLineServiceImpl.add(invoiceLine);
**метод add наследуется от этого GenericDao:**
package dao; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; @SuppressWarnings("unchecked") public abstract class GenericDaoHibernateImpl<E, PK extends Serializable> implements GenericDao<E, PK> { /** * By defining this class as abstract, we prevent Spring from creating * instance of this class If not defined as abstract, * getClass().getGenericSuperClass() would return Object. There would be * exception because Object class does not hava constructor with parameters. */ protected Class<? extends E> daoType; public static SessionFactory sessionFactory; @SuppressWarnings("rawtypes") public GenericDaoHibernateImpl() { Type t = getClass().getGenericSuperclass(); ParameterizedType pt = (ParameterizedType) t; daoType = (Class) pt.getActualTypeArguments()[0]; } static { try { sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (Throwable t) { t.printStackTrace(); } } public static SessionFactory getSession() { return sessionFactory; } protected Session currentSession() { return getSession().getCurrentSession(); } @Override public void add(E entity) { currentSession().beginTransaction(); currentSession().save(entity); currentSession().getTransaction().commit(); } @Override public void update(E entity) { currentSession().beginTransaction(); currentSession().update(entity); currentSession().getTransaction().commit(); } @Override public void remove(E entity) { currentSession().beginTransaction(); // E oldEntity = (E) currentSession().l; currentSession().delete(entity); currentSession().getTransaction().commit(); } @Override public E find(PK key) { currentSession().beginTransaction(); return (E) currentSession().get(daoType, key); } @Override public List<E> getAll() { currentSession().beginTransaction(); return currentSession().createCriteria(daoType).list(); } }
**Обратите внимание, что метод add отлично работает для других сущностей, таких как Product, так что это заставило меня подумать, что проблема заключается в xml-отображении Invoiceline, а не в java-коде**
Это моя сущность * * InvoiceLine**
package model; import java.io.Serializable; public class InvoiceLine implements Serializable{ private long id; private double total; public double getTotal() { return total; } public void setTotal(double total) { this.total = total; } public long getId() { return id; } public void setId(int id) { this.id = id; } private Product product; private Invoice invoice; private int quantity; public InvoiceLine() { super(); } public InvoiceLine(int quantity) { super(); this.quantity= quantity; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } public Invoice getInvoice() { return invoice; } public void setInvoice(Invoice invoice) { this.invoice= invoice; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity= quantity; } }
** Сущность продукта**
package model; import java.io.Serializable; import java.util.HashSet; import java.util.Set; public class Product implements Serializable{ private int codeProduct; private String name; private String description; private Double price; private int quantityStock; private Category category; private Set<InvoiceLine> invoiceLine= new HashSet<InvoiceLine>(); public Set<InvoiceLine> getInvoiceLine() { return invoiceLine; } public void setInvoiceLine(Set<InvoiceLine> invoiceLine) { this.invoiceLine= invoiceLine; } public Product() { } public Product(String name, String description, Double price, int quantityStock) { this.name = name; this.description = description; this.price = price; this.quantityStock = quantityStock; } // getters and setters public int getCodeProduct() { return codeProduct; } public void setCodeProduct(int codeProduct) { this.codeProduct = codeProduct; } public String getName() { return name; } public void setName(String name) { this.name= name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price= price; } public Category getCategory() { return category; } public void setCategory(Category category) { this.category = category; } public int getQuantityStock() { return quantityStock; } public void setQuantityStock(int quantityStock) { this.quantityStock = quantityStock; } }