I have two entities defined as:
#Entity
public class FileMaster implements java.io.Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long fileId;
#NotNull
#Column(unique = true)
private String fileNumber = "";
private String subject = "";
#Temporal(TemporalType.DATE)
private Date date=null;
private String authPerson="";
private String authDesign="";
private String department="";
#OneToMany(mappedBy = "fileMaster", cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name="id")
private Set<FileDetail> fileDetail = new HashSet<FileDetail>();
and second entity:
#Entity
public class FileDetail implements java.io.Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long pdfId;
//#NotNull
#Column(unique = true)
private String name;
//#NotNull
#ManyToOne
private FileMaster fileMaster;
the following code simply tries to persist the two master-detail tables.. First insert goes well and it commits the record:
Set<FileDetail> pdfFileNames = newUpload.getPdfFileNames();
EntityManager em = Persistence.createEntityManagerFactory("fms")
.createEntityManager();
em.getTransaction().begin();
FileMaster fileMaster = new FileMaster();
fileMaster.setFileNumber((String) editorForm.getField("fileNumber").getValue());
fileMaster.setSubject((String) editorForm.getField("subject").getValue());
fileMaster.setAuthDesign((String)
editorForm.getField("authDesign").getValue());
fileMaster.setAuthPerson((String) editorForm.getField("authPerson").getValue());
fileMaster.setDate((Date) editorForm.getField("date").getValue());
fileMaster.setFileDetail(pdfFileNames);
em.persist(fileMaster);
Iterator<FileDetail> iter = pdfFileNames.iterator();
while(iter.hasNext()) {
FileDetail fileDetail = iter.next();
fileDetail.setName(fileDetail.getName());
fileDetail.setFileMaster(fileMaster);
em.persist(fileDetail);
}
em.getTransaction().commit();
em.close();
When I try to insert the second record.... It gives me PSQLException. Since Iam new to JPA... BTW Iam using Eclipselink and PostgreSQL with JPA....Iam finding it hard to resolve this issue. Could anyone please help me over this issue... let me paste the traces as well...
May 27, 2012 10:08:02 AM com.vaadin.Application terminalError
SEVERE: Terminal error:
com.vaadin.event.ListenerMethod$MethodException
Cause: javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "filedetail_pkey"
Detail: Key (pdfid)=(306) already exists.
Error Code: 0
Call: INSERT INTO FILEDETAIL (PDFID, NAME, FILEMASTER_FILEID) VALUES (?, ?, ?)
bind => [306, Manning Java Persistence with Hibernate 2nd.pdf, 3]
Query: InsertObjectQuery(Manning Java Persistence with Hibernate 2nd.pdf)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:532)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:164)
at com.vaadin.ui.AbstractComponent.fireEvent(AbstractComponent.java:1219)
at com.vaadin.ui.Button.fireClick(Button.java:550)
at com.vaadin.ui.Button.changeVariables(Button.java:217)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.changeVariables(AbstractCommunicationManager.java:1451)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariableBurst(AbstractCommunicationManager.java:1399)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariables(AbstractCommunicationManager.java:1318)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:763)
at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:296)
at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:598)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:486)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:413)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111)
at org.eclipse.jetty.server.Server.handle(Server.java:350)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:900)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:954)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:851)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:606)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "filedetail_pkey"
Detail: Key (pdfid)=(306) already exists.
Error Code: 0
Call: INSERT INTO FILEDETAIL (PDFID, NAME, FILEMASTER_FILEID) VALUES (?, ?, ?)
bind => [306, Manning Java Persistence with Hibernate 2nd.pdf, 3]
Query: InsertObjectQuery(Manning Java Persistence with Hibernate 2nd.pdf)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(Entit yTransactionImpl.java:102)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransac tionImpl.java:63)
at com.complete.raspberry.webui.PersonEditor.save(PersonEditor.java:178)
at com.complete.raspberry.webui.PersonEditor.buttonClick(PersonEditor.java:120)
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 com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:512)
... 36 more
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
You should use GenerationType.IDENTITY to generate pdfid using auto increment instead of GenerationType.AUTO for FileDetail entity.
#Entity
public class FileDetail implements java.io.Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long pdfId;
}
GenerationType.IDENTITY
Indicates that the persistence provider must assign primary keys for
the entity using a database identity column.
Try setting logging on finest to see what is occurring.
Where does pdfFileNames come from? Are this existing objects, with existing ids? If they are existing, you should either be find/merging them, or create new ones with null ids. Ensure they do not have existing ids when you call persist.
If using SEQUENCE also ensure your increment matches your allocation size (default is 50).
Related
Using WildFly Full 17.0.1.Final (WildFly Core 9.0.2.Final) / EclipseLink 2.7.7 with MySQL server, I have few fields (of enum type, of Instant as well) in a parent entity (#MappedSuperclass) that I want to inherit in few sub-entities.
The problem I have is that the annotation #Enumerated(STRING), put in the parent entity fields, is not taken into account and EclipseLink is trying to persist the enums as integers instead of as strings.
The same issue with Instant type fields - the annotation #Convert(converter = InstantConverter.class) is not taken into account
When I move the fields to live in the child entities (not using inheritance), it works as expected.
Here is the code:
#MappedSuperclass
#Access(AccessType.PROPERTY)
public abstract class BaseEntity {
#Id
#Column(name = "ID", nullable = false)
private String id;
#Column(name = "STATUS", nullable = false)
#Enumerated(EnumType.STRING)
private StatusEnum status;
#Column(name = "TIMESTAMP", nullable = false)
#Convert(converter = InstantConverter.class)
private Instant timestamp;
// ... getters, setters
}
#Entity
#Table(name = "child1")
public class ChildEntity extends BaseEntity {
// other fields with getters and setters
}
The exceptions:
[EL Warning]: UnitOfWork(353321401)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '\xAC\xED\x00\x05sr\x00\x0Djava.time.Ser\x95]\x84\xBA\x1B"H\xB2\x0C\x00\x00xpw\x0D\x02\x00\x00\x00\x00aI\xD3\x86\x1B\xDD\xBCTx' for column 'TIMESTAMP' at row 1
[EL Warning]: UnitOfWork(597716366)--Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [FAILURE], of class [class java.lang.String], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[status-->d.s.STATUS]] with descriptor [RelationalDescriptor(d.e.ChildEntity --> [DatabaseTable(...)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "FAILURE"
Any idea how to resolve this problem?
Edit: There is no #Entity annotation on BaseEntity class as it is #MappedSuperclass. There is no table in DB behind it as well and this is the desired model. I just mention it, don't know if it is related to the issue.
I'm constantly getting error when i wanna insert some data
Project Class
#Entity
#NamedQueries({
#NamedQuery(name = "Project.findAll",
query = "SELECT p FROM Project p"),
#NamedQuery(name = "Project.findByTitle",
query = "SELECT p FROM Project p WHERE p.title = :title")
})
public class Project implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int projectId;
#Column
private String title;
#Column
private String description;
#Column
private Date projectDate;
#ManyToOne
#JoinColumn(name = "projectStatusId")
private ProjectStatus projectStatus;
#OneToMany(mappedBy = "projectMemberId",fetch = FetchType.EAGER)
private List<ProjectMember> memberList = new ArrayList<ProjectMember>();
/**
* Setters and Getters
*/
}
ProjectMember Class
#Entity
#NamedQueries({
#NamedQuery(name = "ProjectMember.findAll",
query = "SELECT pm FROM ProjectMember pm"),
#NamedQuery(name = "ProjectMember.findByProject",
query = "SELECT pm FROM ProjectMember pm WHERE pm.project = :project"),
#NamedQuery(name = "ProjectMember.findByUser",
query = "SELECT pm FROM ProjectMember pm WHERE pm.user = :user"),
#NamedQuery(name = "ProjectMEmeber.findByUserAndProject",
query = "SELECT pm FROM ProjectMember pm WHERE pm.user = :user AND pm.project = :project")
})
public class ProjectMember implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int projectMemberId;
#Column
private Date activationDate;
#Column
private Date lastActiveDate;
#ManyToOne
#JoinColumn(name = "memberStatusId")
private MemberStatus memberStatus;
#ManyToOne
#JoinColumn(name = "projectId")
private Project project;
#ManyToOne
#JoinColumn(name = "memberRoleId")
private MemberRole memberRole;
#ManyToOne
#JoinColumn(name = "userId")
private User user;
/**
* Setter and Getter
*/
}
that's how i run it
ProjectController Class
public String createProject(){
project.setProjectDate(new Date());
project.setProjectStatus(new ProjectStatusFacade().findByStatus("active"));
ProjectMember projectMember = new ProjectMember();
projectMember.setMemberStatus(new MemberStatusFacade().findByStatus("accepted"));
projectMember.setMemberRole(new MemberRoleFacade().findByRole("team leader"));
projectMember.setActivationDate(new Date());
projectMember.setUser(userSession.getUser());
new ProjectFacade().create(project);
System.out.print(project);
projectMember.setProject(project);
new ProjectMemberFacade().create(projectMember);
userSession.setUser(new UserFacade().findById(userSession.getUser().getUserId()));
return "index?faces-redirect=true";
}
and that's what i get in the end
Caused by: javax.faces.el.EvaluationException: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
... more exceptions
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
... more exceptions
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
...more exceptions
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`goent`.`projectmember`, CONSTRAINT `FKfyw2iinfhhsbrmqbu1sr7l93q` FOREIGN KEY (`projectMemberId`) REFERENCES `project` (`projectId`))
... more exceptions
15:51:06,449 ERROR [io.undertow.request] (default task-4) UT005023: Exception handling request to /hibernate/pages/project-add-member.xhtml: javax.servlet.ServletException: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
... more exceptions
Caused by: javax.faces.el.EvaluationException: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
... more exceptions
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
...more exceptions
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
... more exceptions
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`goent`.`projectmember`, CONSTRAINT `FKfyw2iinfhhsbrmqbu1sr7l93q` FOREIGN KEY (`projectMemberId`) REFERENCES `project` (`projectId`))
... more exceptions
Using: Java, JPA, Hibernate, MySQL5.7
The cause of exception is :
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`goent`.`projectmember`, CONSTRAINT `FKfyw2iinfhhsbrmqbu1sr7l93q` FOREIGN KEY (`projectMemberId`) REFERENCES `project` (`projectId`))
Your action is violating foreign key constraint for projectMemberId column in projectmember table, which is referencing projectId column of project table as per your defined specifications.
This is what most likely is happening.
In the Project entity, you are telling the persistence provider to always eagerly fetch the ProjectNames:
#OneToMany(mappedBy = "projectMemberId",fetch = FetchType.EAGER)
private List<ProjectMember> memberList = new ArrayList<ProjectMember>();
Then in the save method you are creating a ProjectName and populating it with the Project. Thats fine, though the list in the Project does not contain that newly created ProjectName.
The dependency has to be set on both sides, so eventually you would need to do following in your method:
project.getMemberList().add(projectName);
Thank you people, finally I could fix the bug. The problem was in Project class, it was about incorrect mapping. Instead of telling variable to map in other class, I was pointing on PK of that class.
I wrote this
Project class
#ManyToOne
#JoinColumn(name = "projectStatusId")
private ProjectStatus projectStatus;
instead this
//Correct code
#ManyToOne
#JoinColumn(name = "project")
private ProjectStatus projectStatus;
after this change the code started work well.
I have the following classes:
Hardware.java
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Hardware{
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
private long id;
private String serialnumber;
#OneToMany (mappedBy="hardware")
private List<Equipment> equipments;
}
Computer.java
#Entity
public class Computer extends Hardware {
private String hostname;
private String macAdress;
private String ipNumber;
public Computer(){
super();
}
public Computer(String serialnumber, String hostname,
String macAdress, String ipNumber) {
super(serialnumber);
this.hostname = hostname;
this.macAdress = macAdress;
this.ipNumber = ipNumber;
}
}
NetworkDeivce.java
#Entity
public class NetworkDevice extends Hardware {
private String hostname;
private String ipAdress;
public NetworkDevice(){
super();
}
public NetworkDevice(String serialnumber, String hostname,
String ipAdress) {
super(serialnumber);
this.hostname = hostname;
this.ipAdress = ipAdress;
}
}
And now the class that is mapped to the Hardware Class:
Equipment.java
#Entity
public class Equipment {
public Equipment(){
}
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
private String serialnumber;
private String info;
#ManyToOne (fetch=FetchType.EAGER)
#JoinColumn(name="HW_ID")
private Hardware hardware;
}
Now if I add a Equipment to a Computer it all works finde, but if I try to add Equipment to a NetworkDevice I get this Error:
Internal Exception:
Internal Exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`inventorytool_beta`.`EQUIPMENT`, CONSTRAINT `FK_EQUIPMENT_HW_ID` FOREIGN KEY (`HW_ID`) REFERENCES `COMPUTER` (`ID`))
Error Code: 1452
Call: INSERT INTO EQUIPMENT (INFO, SERIALNUMBER, HW_ID) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(domain.hardware.Equipment#600a620d)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
at main.dbTest(main.java:74)
at main.main(main.java:18)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`inventorytool_beta`.`EQUIPMENT`, CONSTRAINT `FK_EQUIPMENT_HW_ID` FOREIGN KEY (`HW_ID`) REFERENCES `COMPUTER` (`ID`))
Error Code: 1452
Call: INSERT INTO EQUIPMENT (INFO, SERIALNUMBER, HW_ID) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(domain.hardware.Equipment#600a620d)
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:851)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:913)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`inventorytool_beta`.`EQUIPMENT`, CONSTRAINT `FK_EQUIPMENT_HW_ID` FOREIGN KEY (`HW_ID`) REFERENCES `COMPUTER` (`ID`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
So I think it's a problem with the inheritance... I'm not very good at JPA..
Thanks in advance.
Have a look at the schema that was generated. You should had three different tables for hardware, due to your inheritance strategy: one for Hardware, one for Computer and one fon NetworkDevice. The problem is that HW_ID can only reference one table. Here your JPA provider chose Computer, probably because it's first in alphabetical order, but it can't handle all three classes.
Consider using another inheritance strategy, like JOIN.
Check the code where you insert Equipment to a NetworkDevice. It looks like HW_ID does not exists in the master-table(Hardware). Because it is trying to insert nonexistent Master-Table HW_ID as foreign-Key in child table(Equipment).
Regards,
Ravi
Yes it comes from your inheritance strategy. You can't use #GeneratedValue(strategy=GenerationType.IDENTITY) with table_per_class.
See Java/Hibernate JPA: InheritanceType.TABLE_PER_CLASS and IDs
I have two 3 tables in my database:
group
----------
groupId PK
name
user_account
----------
userId PK
user_grouping
----------
groupId PK FK grouping(groupId -> groupId)
userId PK FK user_account(userId -> userId)
In my UserAccount Entity, I have the following line:
#JoinTable(name = "user_group", joinColumns = {
#JoinColumn(name = "userId", referencedColumnName = "userId")}, inverseJoinColumns = {
#JoinColumn(name = "groupId", referencedColumnName = "groupId")})
#ManyToMany
private List<Grouping> groupingList;
This is to show the relationship between all the tables. However, when I deploy, I get the following error:
SEVERE: Exception while preparing the app : Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [com.dv_model_ejb_1.0-SNAPSHOTPU] failed.
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The #JoinColumns on the annotated element [field groupingList] from the entity class [class com.dv.model.entity.UserAccount] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn.
Local Exception Stack:
Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [com.dv_model_ejb_1.0-SNAPSHOTPU] failed.
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The #JoinColumns on the annotated element [field groupingList] from the entity class [class com.dv.model.entity.UserAccount] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn.
at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:221)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1402)
...
I am not sure exactly how to interpret this error message. I am assuming I do not have the table relationship correctly modeled in my entity. But I am not sure why. Before today, this was compiling fine. Can anyone provide assistance?
Description of tables is inconsistent (grouping vs group) and name of join table in entity mappings is not one of the table names. Because of these
inconsistencies I assume following table structure:
useraccount (userid PK)
grouping (groupdid PK, name)
user_grouping (userId PK, groupId PK)
- FK userId references to user_account.userid
- FK groupId references to grouping.groupId
One correct way to map this to two entities is following:
#Entity
public class UserAccount {
#Id int userId;
#JoinTable(name = "user_grouping", joinColumns = {
#JoinColumn(name = "userId", referencedColumnName = "userId")},
inverseJoinColumns = {
#JoinColumn(name = "groupId", referencedColumnName = "groupId")})
#ManyToMany
private List<Grouping> groupingList;
//get and set omitted.
}
#Entity
public class Grouping {
#Id int groupId;
String name;
//get,set, and optional inverse side of relationship omitted
}
used: hibernate 3.6.2, maven 2, postgres 9.
I have code that must work but it doesn't. When I launch functional test I've got the error:
java.lang.ClassCastException: org.hibernate.action.DelayedPostInsertIdentifier cannot be cast to java.lang.Long
Code is a standart domain model:
Entity:
#Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
#Entity
#Table(schema = "simulators", name = "mySimulator_card")
public class MySimulatorCard {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "account_number", unique = true, nullable = false)
private String accountNumber;
etc...
DAO:
public abstract class AbstractDao<E, PK extends Serializable> implements Dao<E, PK> {
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
#PersistenceContext(unitName = "MySimulator")
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public abstract Class<E> getEntityClass();
#Override
public void persist(E e) {
getEntityManager().persist(e);
}
#Override
public E merge(E e) {
return getEntityManager().merge(e);
}
#Override
public void refresh(E e) {
getEntityManager().refresh(e); //<-- some thing wroooong
}
#Override
public void delete(E e) {
getEntityManager().remove(e);
}
etc...
And according table:
CREATE TABLE simulators.mySimulator_card
(
id bigserial NOT NULL,
account_number character varying(255) NOT NULL,
etc...
CONSTRAINT mySimulator_card_pk PRIMARY KEY (id),
CONSTRAINT mySimulator_card_account_fk FOREIGN KEY (account_id)
REFERENCES simulators.mySimulator_account (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT mySimulator_card_currency_fk FOREIGN KEY (currency_id)
REFERENCES simulators.mySimulator_currency ("name") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT mySimulator_card_product_fk FOREIGN KEY (product_id)
REFERENCES simulators.mySimulator_product (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT mySimulator_account_account_number_uq UNIQUE (account_number),
CONSTRAINT mySimulator_card_san_uq UNIQUE (san)
)
WITH (
OIDS=FALSE
);
ALTER TABLE simulators.mySimulator_card OWNER TO functional;
Here are stack trace till my code:
at org.hibernate.type.descriptor.java.LongTypeDescriptor.unwrap(LongTypeDescriptor.java:36)
at org.hibernate.type.descriptor.sql.BigIntTypeDescriptor$1.doBind(BigIntTypeDescriptor.java:52)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:91)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:282)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:277)
at org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1873)
at org.hibernate.loader.Loader.bindParameterValues(Loader.java:1844)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1716)
at org.hibernate.loader.Loader.doQuery(Loader.java:801)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2037)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3293)
at org.hibernate.event.def.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:151)
at org.hibernate.event.def.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:62)
at org.hibernate.impl.SessionImpl.fireRefresh(SessionImpl.java:1118)
at org.hibernate.impl.SessionImpl.refresh(SessionImpl.java:1098)
at org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:738)
at org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:713)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
at $Proxy153.refresh(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy82.refresh(Unknown Source)
at com.goooogle.simulator.mysimulator.dao.AbstractDao.refresh(AbstractDao.java:42)
Why? Is it hibernate's bug?
I had faced exactly same exception when doing a save(). I solved it by correcting the cascade option in the hibernate mapping file. I changed it from "all-delete-orphan,save-update, delete "to "save-update, delete, delete-orphan" and it worked for me.
Hope it helps.
This exception baffled me just today and happened in a Spring Boot application using the JpaRepository.
In my case this occured when a JpaRepostitory.findBySomeEntity was called. SomeEntity had been saved in the same transaction using JpaRepository.save(...) rather than JpaRepository.saveAndFlush(...). Therefore its ID was not yet set.
Looks like Hibernate is trying to substitute the missing entity id with the DelayedPostInsertIdentifier created in the uncommitted save-transaction even though it can't be cast to the id-type.
It's a misleading Exception. Good thing it was easily fixed by the saveAndFlush(...).
Is your driver and dialect correct in your hibernate.properties file?
hibernate.connection.driver_class = org.postgresql.Driver
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html_single/#configuration-hibernatejdbc
You didn't define your primary key as IDENTITY on your create table statement.
id bigserial NOT NULL IDENTITY
I understand that the question was asked pretty while ago, but there is no answer for my case and I had to deal it myself.
So in my case the issue was in Parent-child Entity relations, I defined non-nullable join column as #JoinColumn(nullable = false) and Hibernate could not insert child Entity without knowing parent ID. Throwing me java.lang.ClassCastException: class org.hibernate.action.internal.DelayedPostInsertIdentifier cannot be cast to class java.lang.Long.
So the fix was in setting #JoinColumn as nullable.
My parent Entity was:
#Entity
public class Quiz {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
#JoinColumn(name = "quiz_id", nullable = false)
#OneToMany(orphanRemoval = true, cascade = CascadeType.ALL, targetEntity = Question.class)
#Fetch(FetchMode.JOIN)
public List<Question> questionList;
}
And my child Entity was:
#Entity
public class Question {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
}
And the fixed Parent Entity:
#Entity
public class Quiz {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
#JoinColumn(name = "quiz_id")
#OneToMany(orphanRemoval = true, cascade = CascadeType.ALL, targetEntity = Question.class)
#Fetch(FetchMode.JOIN)
public List<Question> questionList;
}
Logically I understand that this was my fault, since it's not possible to insert non-nullable ID when you don't know it, but Hibernate could thrown better, not so confusing, exception.
And yes, after the fix Hibernate issues additional Entity update to set parent ID:
DEBUG [org.hib.SQL] insert into Quiz (user_name) values ($1) returning id
DEBUG [org.hib.SQL] insert into Question (question) values ($1) returning id
DEBUG [org.hib.SQL] update Question set quiz_id=$1 where id=$2