Hi
I have an entity 'Questionnaire' with a many-to-one relationship on entity 'Questionnairetemplate'.
So several questionnaires are linked to the same template.
When I try to persist a new 'Questionnaire' in the database, the insert statement generated by Hibernate doesn't contain the column 'questionnairetemplateid' which represent the link many-to-one in the database.
The code looks correct and Hibernate detects that an instance QuestionnaireTemplate is set into the new Questionnaire instance according to the code.
Something special is that the foreign key on the 'QuestionnaireTemplate' is using one of the column of the 'Questionnaire' primary key ( the 'Year' column ).
Any idea why the insert statement is incomplete ?
Where can I have look in order to find more details about the generation of the insert statement ?
Thanks in advance for your help.
Regards,
Christophe
Hibernate version:
Hibernate EntityManager 3.2.0.CR1
Hibernate Annotations 3.2.0.CR1
Hibernate 3.2 cr2
Code between sessionFactory.openSession() and session.close():
Questionnaire questionnaire = new Questionnaire();
questionnaire.setId(questionnaireId);
Questionnairetemplate questionnairetemplate = questionnaireTemplateDAO.findById(questionnairetemplateId);
questionnaire.setQuestionnairetemplate(questionnairetemplate);
entityManager.persist(questionnaire);
Name and version of the database you are using:
MySQL Server 5.0
Debug level Hibernate log excerpt:
Code:
[testng] DEBUG 04-10 10:23:43,828 (Log4JLogger.java:debug:84) -generated identifier: component[companyId,financialStatementId,screeningTypeId,year]{companyId=1, year=2005, screeningTypeId=2, financialStatementId=1}, using strategy: org.hibernate.id.Assigned
[testng] DEBUG 04-10 10:23:43,843 (Log4JLogger.java:debug:84) -merge successful
[testng] DEBUG 04-10 10:23:43,859 (Log4JLogger.java:debug:84) -processing flush-time cascades
[testng] DEBUG 04-10 10:23:43,859 (Log4JLogger.java:debug:84) -dirty checking collections
[testng] DEBUG 04-10 10:23:43,875 (Log4JLogger.java:debug:84) -Collection found: [accountingAudit.businessObjects.Questionnairetemplate.questionnairetypes#component[questionnaireId,year]{questionnaireId=1, year=2005}], was: [accountingAudit.businessObjects.Questionnairetemplate.questionnairetypes#component[questionnaireId,year]{questionnaireId=1, year=2005}] (uninitialized)
[testng] DEBUG 04-10 10:23:43,875 (Log4JLogger.java:debug:84) -Collection found: [accountingAudit.businessObjects.Questionnairetemplate.questionnaires#component[questionnaireId,year]{questionnaireId=1, year=2005}], was: [accountingAudit.businessObjects.Questionnairetemplate.questionnaires#component[questionnaireId,year]{questionnaireId=1, year=2005}] (uninitialized)
[testng] DEBUG 04-10 10:23:43,875 (Log4JLogger.java:debug:84) -Collection found: [accountingAudit.businessObjects.Questionnairetemplate.questionnairegroups#component[questionnaireId,year]{questionnaireId=1, year=2005}], was: [accountingAudit.businessObjects.Questionnairetemplate.questionnairegroups#component[questionnaireId,year]{questionnaireId=1, year=2005}] (uninitialized)
[testng] DEBUG 04-10 10:23:43,890 (Log4JLogger.java:debug:84) -Collection found: [accountingAudit.businessObjects.Questionnaire.answers#component[companyId,financialStatementId,screeningTypeId,year]{companyId=1, year=2005, screeningTypeId=2, financialStatementId=1}], was: [<unreferenced>] (initialized)
[testng] DEBUG 04-10 10:23:43,890 (Log4JLogger.java:debug:84) -Flushed: 1 insertions, 0 updates, 0 deletions to 2 objects
[testng] DEBUG 04-10 10:23:43,890 (Log4JLogger.java:debug:84) -Flushed: 1 (re)creations, 0 updates, 0 removals to 4 collections
[testng] DEBUG 04-10 10:23:43,906 (Log4JLogger.java:debug:84) -listing entities:
[testng] DEBUG 04-10 10:23:43,906 (Log4JLogger.java:debug:84) -accountingAudit.businessObjects.Questionnairetemplate{enforcementyear=accountingAudit.businessObjects.Enforcementyear#2005, questionnaires=<uninitialized>, questionnairetypes=<uninitialized>, questionnairegroups=<uninitialized>, question=accountingAudit.businessObjects.Question#component[questionId,year]{year=2005, questionId=1}, id=component[questionnaireId,year]{questionnaireId=1, year=2005}}
[testng] DEBUG 04-10 10:23:43,906 (Log4JLogger.java:debug:84) -accountingAudit.businessObjects.Questionnaire{financialstatement=null, screeningtype=null, concludingRemarks=null, answers=[], questionnairetemplate=accountingAudit.businessObjects.Questionnairetemplate#component[questionnaireId,year]{questionnaireId=1, year=2005}, userByConcludedUserId=null, concludedTimestamp=null, lastEditedTimestamp=null, userByLastEditedUserId=null, id=component[companyId,financialStatementId,screeningTypeId,year]{companyId=1, year=2005, screeningTypeId=2, financialStatementId=1}}
[testng] DEBUG 04-10 10:23:43,937 (Log4JLogger.java:debug:84) -about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
[testng] DEBUG 04-10 10:23:43,937 (Log4JLogger.java:debug:84) -opening JDBC connection
[testng] DEBUG 04-10 10:23:43,937 (Log4JLogger.java:debug:84) -insert into accountingaudit.questionnaire (LastEditedUserId, ConcludedUserId, LastEditedTimestamp, ConcludingRemarks, ConcludedTimestamp, CompanyId, FinancialStatementId, ScreeningTypeId, Year) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
[testng] Hibernate: insert into accountingaudit.questionnaire (LastEditedUserId, ConcludedUserId, LastEditedTimestamp, ConcludingRemarks, ConcludedTimestamp, CompanyId, FinancialStatementId, ScreeningTypeId, Year) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
[testng] DEBUG 04-10 10:23:43,953 (Log4JLogger.java:debug:84) -Executing batch size: 1
[testng] DEBUG 04-10 10:23:44,296 (Log4JLogger.java:debug:84) -about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
[testng] DEBUG 04-10 10:23:44,296 (Log4JLogger.java:debug:84) -skipping aggressive-release due to flush cycle
[testng] DEBUG 04-10 10:23:44,312 (Log4JLogger.java:debug:89) -Could not execute JDBC batch update [insert into accountingaudit.questionnaire (LastEditedUserId, ConcludedUserId, LastEditedTimestamp, ConcludingRemarks, ConcludedTimestamp, CompanyId, FinancialStatementId, ScreeningTypeId, Year) values (?, ?, ?, ?, ?, ?, ?, ?, ?)]
[testng] java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`accountingaudit/questionnaire`, CONSTRAINT `Ref_36` FOREIGN KEY (`Year`, `QuestionnaireId`) REFERENCES `questionnairetemplate` (`Year`, `QuestionnaireId`) ON DELETE NO ACTION ON UPDATE NO ACT)34
Mapping annotations:Code:
@Entity
@Table(name = "questionnaire", catalog = "accountingaudit", uniqueConstraints = {})
public class Questionnaire implements java.io.Serializable {
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name = "year", column = @Column(name = "Year", unique = false, nullable = false, insertable = true, updatable = true)),
@AttributeOverride(name = "companyId", column = @Column(name = "CompanyId", unique = false, nullable = false, insertable = true, updatable = true)),
@AttributeOverride(name = "financialStatementId", column = @Column(name = "FinancialStatementId", unique = false, nullable = false, insertable = true, updatable = true)),
@AttributeOverride(name = "screeningTypeId", column = @Column(name = "ScreeningTypeId", unique = false, nullable = false, insertable = true, updatable = true)) })
public QuestionnaireId getId() {
return this.id;
}
@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
@JoinColumns( {
@JoinColumn(name = "Year", referencedColumnName = "Year", unique = false, nullable = false, insertable = false, updatable = false),
@JoinColumn(name = "QuestionnaireTemplateId", referencedColumnName = "QuestionnaireTemplateId", unique = false, nullable = false, insertable = false, updatable = false) })
public Questionnairetemplate getQuestionnairetemplate() {
return this.questionnairetemplate;
}
Code:
@Entity
@Table(name = "questionnairetemplate", catalog = "accountingaudit", uniqueConstraints = {})
public class Questionnairetemplate implements java.io.Serializable {
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name = "year", column = @Column(name = "Year", unique = false, nullable = false, insertable = true, updatable = true)),
@AttributeOverride(name = "questionnaireTemplateId", column = @Column(name = "QuestionnaireTemplateId", unique = false, nullable = false, insertable = true, updatable = true)) })
public QuestionnairetemplateId getId() {
return this.id;
}
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "questionnairetemplate")
public Set<Questionnaire> getQuestionnaires() {
return this.questionnaires;
}
Code:
@Embeddable
public class QuestionnaireId implements java.io.Serializable {
@Column(name = "Year", unique = false, nullable = false, insertable = true, updatable = true)
public int getYear() {
return this.year;
}
@Column(name = "CompanyId", unique = false, nullable = false, insertable = true, updatable = true)
public long getCompanyId() {
return this.companyId;
}
@Column(name = "FinancialStatementId", unique = false, nullable = false, insertable = true, updatable = true)
public short getFinancialStatementId() {
return this.financialStatementId;
}
@Column(name = "ScreeningTypeId", unique = false, nullable = false, insertable = true, updatable = true)
public byte getScreeningTypeId() {
return this.screeningTypeId;
}
SQL for the table :
Code:
CREATE TABLE `questionnaire` (
`Year` int(4) UNSIGNED NOT NULL DEFAULT '0',
`CompanyId` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`FinancialStatementId` smallint(6) UNSIGNED NOT NULL DEFAULT '0',
`ScreeningTypeId` tinyint(3) UNSIGNED NOT NULL DEFAULT '0',
`QuestionnaireTemplateId` int(11) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY(`Year`, `CompanyId`, `FinancialStatementId`, `ScreeningTypeId`)
)
...
ALTER TABLE `questionnaire` ADD
CONSTRAINT `Ref_36` FOREIGN KEY (`Year`, `QuestionnaireTemplateId`)
REFERENCES `questionnairetemplate`(`Year`, `QuestionnaireTemplateId`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;