问题描述
我了解 JPA
并负责制作数据库并为其插入一些值。我想知道如何找出最近插入的对象的ID是什么,所以我找到了一种方法,我需要使用 flush
的方法EntityManager
。
I learn about JPA
and had task to make database and insert some values to it. I wondered how I can find out what was the ID of recently inserted object, so I found a way that I need to use flush
method of EntityManager
.
不幸的是我得到了
当我使用上述方法时异常。我认为问题在于我的数据库在自动增量上设置了所有 ID
(我使用ORACLE 11G Express ),因此在提交之前它已经 null
value并回滚事务。
exception when I use the above method. I think the problem lies in that my database has all ID's
set on autoincrement ( I use ORACLE 11G Express ), so before commiting it has null
value and it rollbacks transaction.
我可以做些什么来修复它?
这是DB(ID的是自动增量[oracle中的序列和触发器]):
This is DB ( ID's are autoincrement[Sequences and Triggers in oracle]):
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();
}
}
@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 + " ]";
}
}
推荐答案
您需要使用 @GeneratedValue ,以便JPA知道数据库将自动生成id:
@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;
Check the docs in the link above.
这篇关于在工作单元克隆中遇到JPA Null或零主键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!