-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Composite Keys w/ Annotations
PostPosted: Fri Nov 11, 2011 3:00 pm 
Newbie

Joined: Fri Nov 11, 2011 2:32 pm
Posts: 2
Hi,

I have a system i'm developing that uses hibernate annotations.

I have 2 main tables; they are a PrintRequestExecution table that holds meta-data and a PrintRequestParameters table that holds a list of parameters associated with an execution. A row in the parameters table is identifiable by its executionID, its parameterSeq (functions as a 'section number'), and its recordID. These are represented as a composite primary key, with executionID being also a foreign key. The executionID is set to auto-increment in the Execution class.

Here's the annotations for the PrintRequestExecution class (yes, i know, parameterses... it's autogenerated):
Code:
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "ExecutionID", unique = true, nullable = false)
public Integer getExecutionId() {
   return this.executionId;
}
public void setExecutionId(Integer executionId) {
   this.executionId = executionId;
}

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "printRequestExecution")
public Set<PrintRequestParametersTO> getPrintRequestParameterses() {
   return this.printRequestParameterses;
}
public void setPrintRequestParameterses(
      Set<PrintRequestParametersTO> printRequestParameterses) {
   this.printRequestParameterses = printRequestParameterses;
}


For PrintRequestParameters:
Code:
@EmbeddedId
@AttributeOverrides( {
      @AttributeOverride(name = "executionId", column = @Column(name = "ExecutionID", nullable = false)),
      @AttributeOverride(name = "parameterSeq", column = @Column(name = "ParameterSeq", nullable = false)),
      @AttributeOverride(name = "recordId", column = @Column(name = "RecordID", nullable = false)) })
public PrintRequestParametersId getId() {
   return this.id;
}

public void setId(PrintRequestParametersId id) {
   this.id = id;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ExecutionID", nullable = false, insertable = false, updatable = false)
public PrintRequestExecutionTO getPrintRequestExecution() {
   return this.printRequestExecution;
}

public void setPrintRequestExecution(PrintRequestExecutionTO printRequestExecution) {
   this.printRequestExecution = printRequestExecution;
}


The PrintRequestParametersId class is very straightforward; just 3 integers, each with an @Column annotation. The class is decorated with @Embeddable.

Now, when I go to save these tables, i will always be saving them at the same time. This is what I'm doing right now:
Code:
PrintRequestExecutionTO executionTO = new PrintRequestExecutionTO();

PrintRequestParametersId paramID = new PrintRequestParametersId();
paramID.setParamSeq(1);
paramID.setRecordID(1);
PrintRequestParametersTO paramTO = new PrintRequestParametersTO();
paramTO.setPrintRequestExecution(executionTO);
paramTO.setId(paramID);


and it's at that point that i do the whole getSession().save() stuff on the two.

The error I get is that I never set paramID's executionID, so it remains null, and hibernate is trying to save 'null' instead of the executionID from that foreign key relationship with the parameters table. So is this possible? and if so how do I accomplish saving this autogenerated key to the composite primary key via a foreign key relationship?

In the composite ID, I have to be able to manually set paramSeq and i'm fine with manually setting recordID, but i'd like executionID to be populated via the foreign key relationship. I obviously could do another DB call to get the id of the last entry, but I would really rather not add DB calls if there's a way to let mappings take care of this for me.

Here's the stack trace, for reference:
Code:
SEVERE: Servlet.service() for servlet springmvc threw exception
java.sql.BatchUpdateException: Cannot insert the value NULL into column 'ExecutionID', table 'dbo.PrintRequestParameters'; column does not allow nulls. INSERT fails.
   at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeBatch(SQLServerPreparedStatement.java:1160)
   at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
   at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
   at org.hibernate.engine.ActionQueue.executeInserts(ActionQueue.java:158)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:268)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
   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 com.<redacted>.persistence.dao.PrintRequestExecutionDAOImpl.save(Unknown Source)
   at com.<redacted>.persistence.helper.PrintRequestDAOHelperImpl.saveRequest(Unknown Source)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy47.saveRequest(Unknown Source)
   at com.<redacted>.business.bo.PrintRequestBOImpl.madeUpRequest(Unknown Source)
   at com.<redacted>.controllers.IndexController.indexify(IndexController.java:32)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
   at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
   at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
   at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
   at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
   at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:669)
   at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:574)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
   at java.lang.Thread.run(Thread.java:619)


Thanks


Top
 Profile  
 
 Post subject: Re: Composite Keys w/ Annotations
PostPosted: Fri Nov 11, 2011 4:12 pm 
Newbie

Joined: Fri Nov 11, 2011 2:32 pm
Posts: 2
I came up with a pseudo-solution.

I didn't realize that Session.save() returns a 'Serializable' that represents the generated ID. I need to reference my executionID at a later point anyway, so all I have done is altered my DAO to return an Integer that i cast out of the Serializable I get when i save the execution entry, store that ID into the parametersID object, then save the parameters entry.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.