I'm having difficulty using the Hiberante / JPA with composite keys, I believe the problem is there, although the generated exception stacktrace points to something that is not superficially related to the problem.
I have already researched the internet about the specific error:
Parameter index out of range (6 > number of parameters, which is 5).
I used a key composed of 5 foreign keys, and the error occurred also informing that the number of parameters were 9 and it should be 8, I searched the internet and found nothing that is related to the way I'm using Hibernate, since this error usually occurs when referring to parameters in queries, which is not my case.
As can be seen in the code below I'm trying to persist a relatively complex object that involves several many-to-one relationships and in this version two of them make up the primary key
Below is a summary of the classes used in the system and lastly the stacktrace when trying to save the entity.
PostDataQualification, I try to save this class:
@Entity
@IdClass(PostDataQualificationID.class)
public class PostDataQualification {
@Id
@Column(name = "idLearningProcess", insertable = false, updatable = false)
private Integer idLearningProcess;
@Id
@Column(name = "idPostData", insertable = false, updatable = false)
private Integer idPostData;
@Column(name = "pontuation", insertable = false, updatable = false, nullable = true)
private Integer pontuation;
@Temporal(TemporalType.TIMESTAMP)
private Date date;
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumns({ @JoinColumn(name = "idLearningProcess", referencedColumnName = "id") })
private LearningProcess learningProcess;
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "idPostData", referencedColumnName = "id", insertable = true, updatable = false, nullable = false, unique = false)
private PostData post;
@ManyToOne(optional=false, fetch=FetchType.EAGER)
@JoinColumn(name = "idClassification", referencedColumnName = "id", nullable = false, insertable = true, updatable = true, unique = false)
private Classification classification;
@ManyToOne(optional=false, fetch=FetchType.EAGER)
@JoinColumn(name = "idContext", referencedColumnName = "id", nullable = false, insertable = true, updatable = true, unique = false)
private Context context;
@ManyToOne(optional = true, fetch = FetchType.EAGER)
@JoinColumn(name = "idEvent", referencedColumnName = "id", nullable = true, insertable = false, updatable = false, unique = false)
private Event event;
Composite ID of the above class:
public class PostDataQualificationID implements Serializable {
private static final long serialVersionUID = -1614666992682125782L;
private Integer idLearningProcess;
private Integer idPostData;
LearningProcess
@Entity
public class LearningProcess {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// bi-directional many-to-one association to Autor
@ManyToOne(cascade = {}, optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "type", referencedColumnName = "id", nullable = false, updatable = true, insertable = true)
private LearningType type;
@Temporal(TemporalType.TIMESTAMP)
Date date;
@Column(length = 250)
String shortDescription; // descrição curta do processo de treinamento
@Column(length = 500)
String description; // descrição em detalhes do processo de treinamento
@OneToMany(mappedBy = "learningProcess")
private Set<PostDataQualification> qualification;
PostData
@Entity
@NamedQueries({
@NamedQuery(name = PostData.NAMED_QUERY_FIND_ORIGINAL_ID, query = "SELECT pd FROM PostData pd WHERE pd.idOriginal = ?"),
@NamedQuery(name = PostData.NAMED_QUERY_FIND_SCREEN_NAME, query = "SELECT pd FROM PostData pd JOIN pd.sourceProfile sp WHERE sp.screenName = ?") })
public class PostData implements Serializable {
/**
*
*/
private static final long serialVersionUID = 7369168234620318745L;
public static final String NAMED_QUERY_FIND_ORIGINAL_ID = "PostData.findByOriginalId";
public static final String NAMED_QUERY_FIND_SCREEN_NAME = "PostData.findByScreenName";
/**
*
*/
/**
* ID no banco de dados, não confundir com o ID original do post.
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* texto integral do post
*
* Apesar de algumas redes como Twitter permitir apenas 140 caracteres,
* estou considerando o uso de outras redes qeu permitem posts bem maiores.
*/
@Column(length = 512)
private String data;
/**
* ID Original do POST conforme fornecido pela Rede Social.
*/
@Column(length = 50, nullable = false)
private String idOriginal;
// bi-directional many-to-one association to Autor
@ManyToOne(cascade = { CascadeType.REFRESH }, fetch = FetchType.EAGER)
@JoinColumn(name = "idSourceProfile", referencedColumnName = "id", nullable = false, updatable = false, insertable = true, foreignKey = @ForeignKey(ConstraintMode.PROVIDER_DEFAULT) )
private Profile sourceProfile;
// bi-directional many-to-many association to SLAContext
/**
* lista os contextos ao qual este post pertence, para cadastrar este post a
* um novo contexto, basta adicionar o post ao contexto.
*/
@ManyToMany(mappedBy = "posts", cascade = {}, fetch = FetchType.EAGER)
private Set<Context> contexts;
// bi-directional many-to-one association to Autor
@ManyToOne(cascade = {}, fetch = FetchType.EAGER)
@JoinColumn(name = "lang", referencedColumnName = "id", nullable = false, updatable = false, insertable = true, foreignKey = @ForeignKey(ConstraintMode.PROVIDER_DEFAULT) )
private Language lang = new Language("pt", "Português");
@ManyToMany(mappedBy = "posts", cascade = {}, fetch = FetchType.LAZY)
private Set<Acquisition> acquisitions;
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = true, updatable = false)
private Date createAt;
SQL generated during the persistence of the PostDataQualification Entity:
Hibernate:
select
classifica_.id,
classifica_.description as descript2_3_,
classifica_.name as name3_3_
from
Classification classifica_
where
classifica_.id=?
Hibernate:
insert
into
PostDataQualification
(idClassification, idContext, date, idLearningProcess, idPostData)
values
(?, ?, ?, ?, ?)
Code used to persist entity:
ObservableList<PostDataQualification> l_items = tableView.getItems();
pm.beginTransaction();
l_items.forEach(pdq -> {
log.info(pdq.toString());
if (pdq.getClassification() != null) {
pm.persist(pdq);
pm.flush();
}
});
pm.commitTransaction();
Exception Released:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1770)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1653)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8390)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3758)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3486)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$350(GlassViewEventHandler.java:385)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$210/34139361.get(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:927)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1765)
... 50 more
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not insert: [com.socialsla.persistence.entity.PostDataQualification]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1303)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:48)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:125)
at org.jboss.weld.proxies.org$jboss$weld$beanProducerMethod-com$socialsla$persistence$factories$SLAEntityManagerFactorymethod_createEntityManager()_$$_WeldClientProxy.flush(org$jboss$weld$beanProducerMethod-com$socialsla$persistence$factories$SLAEntityManagerFactorymethod_createEntityManager()_$$_WeldClientProxy.java)
at com.socialsla.persistence.PersistenceManager.flush(PersistenceManager.java:403)
at com.socialsla.gui.controllers.ManualClassificationController.lambda$7(ManualClassificationController.java:512)
at com.socialsla.gui.controllers.ManualClassificationController$$Lambda$435/1969723339.accept(Unknown Source)
at java.lang.Iterable.forEach(Iterable.java:75)
at com.socialsla.gui.controllers.javafx.PostDataQualificationObservableList.forEach(PostDataQualificationObservableList.java:417)
at com.socialsla.gui.controllers.ManualClassificationController.saveAllPostDataQualification(ManualClassificationController.java:508)
at com.socialsla.gui.controllers.ManualClassificationController.handleSave(ManualClassificationController.java:246)
... 60 more
Caused by: org.hibernate.exception.GenericJDBCException: could not insert: [com.socialsla.persistence.entity.PostDataQualification]
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2848)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3323)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:447)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:333)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:335)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1224)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1300)
... 74 more
Caused by: java.sql.SQLException: Parameter index out of range (6 > number of parameters, which is 5).
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1094)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:997)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:983)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:928)
at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3688)
at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3670)
at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3715)
at com.mysql.jdbc.PreparedStatement.setNull(PreparedStatement.java:3755)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:60)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:260)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:255)
at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:342)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrateId(AbstractEntityPersister.java:2574)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2542)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2820)
... 82 more