JPA Zero or zero primary key found in clone unit of work

I learned about JPA and had the task of creating a database and inserting some values ​​into it. I wondered how I can find out what the identifier of a newly inserted object is, so I found the way I need to use the flush EntityManager method.

Sorry, I received

Zero or zero primary key found in clone unit of work

an exception when I use the above method. I think the problem is that my database has all the ID's set to auto-increment ( I use ORACLE 11G Express ), so before committing it, it will have a null value and it will roll back the transaction.

What can I do to fix this?

This is DB (ID is auto-increment [Sequences and triggers in oracle]): 2GF7UM2.png

 public class Client { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("JpaIntroductionPU"); EntityManager em = emf.createEntityManager(); EntityTransaction et = em.getTransaction(); et.begin(); Address ad1 = new Address(); ad1.setStreet("Skaraktki"); ad1.setCode("64-340"); em.persist(ad1); em.flush(); System.out.println(ad1.getAId()); et.commit(); } } 

Class address

 @Entity @Table(name = "ADDRESS") @NamedQueries({ @NamedQuery(name = "Address.findAll", query = "SELECT a FROM Address a"), @NamedQuery(name = "Address.findByAId", query = "SELECT a FROM Address a WHERE a.aId = :aId"), @NamedQuery(name = "Address.findByStreet", query = "SELECT a FROM Address a WHERE a.street = :street"), @NamedQuery(name = "Address.findByCode", query = "SELECT a FROM Address a WHERE a.code = :code")}) public class Address implements Serializable { private static final long serialVersionUID = 1L; // @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation @Id @Basic(optional = false) @Column(name = "A_ID") private BigDecimal aId; @Basic(optional = false) @Column(name = "STREET") private String street; @Basic(optional = false) @Column(name = "CODE") private String code; @OneToOne(cascade = CascadeType.ALL, mappedBy = "aId") private Employee employee; @OneToOne(cascade = CascadeType.ALL, mappedBy = "aId") private Department department; public Address() { } public Address(BigDecimal aId) { this.aId = aId; } public Address(BigDecimal aId, String street, String code) { this.aId = aId; this.street = street; this.code = code; } public BigDecimal getAId() { return aId; } public void setAId(BigDecimal aId) { this.aId = aId; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public Employee getEmployee() { return employee; } public void setEmployee(Employee employee) { this.employee = employee; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } @Override public int hashCode() { int hash = 0; hash += (aId != null ? aId.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Address)) { return false; } Address other = (Address) object; if ((this.aId == null && other.aId != null) || (this.aId != null && !this.aId.equals(other.aId))) { return false; } return true; } @Override public String toString() { return "jpaintroduction.Address[ aId=" + aId + " ]"; } } 
+8
java java-ee sql oracle jpa
source share
2 answers

You need to annotate your id field @GeneratedValue so that the JPA knows that the database will automatically generate an identifier:

 @Id @Basic(optional = false) @Column(name = "A_ID") @SequenceGenerator( name = "mySeq", sequenceName = "MY_SEQ", allocationSize = 1, initialValue = 1 ) @GeneratedValue(strategy=GenerationType.IDENTITY, generator="mySeq") private BigDecimal aId; 

Using the oracle, you can use GenerationType.IDENTITY and @SequenceGenerator , in which case you do not need a trigger to request a sequence and populate an identifier, JPA will do it for you. I'm not sure if GenerationType.AUTO will work with oracle, but if so, you will need a trigger to request the sequence and populate the identifier. GenerationType.TABLE is the most portable solution, since you use an independent table managed by JPA to store the sequence, it works in all databases.

Check the documents in the link above.

+4
source share

This happened to me because I manually added an entry to my database with identifier 0 (zero). In my case, EclipseLink could not handle an identifier with zero. So I added the following to my persistence.xml:

  <property name="eclipselink.allow-zero-id" value="true"/> 

This property says that EclipseLink treats zero as a valid identifier.

[1] http://meetrohan.blogspot.de/2011/11/eclipselink-null-primary-key.html

+15
source share

All Articles