JPA Null 또는 0 기본 키가 워크 클론 단위에 있습니다.
나는 에 대해 배웁니다.JPA
데이터베이스를 만들고 거기에 몇 가지 값을 삽입하는 작업을 했습니다.최근에 삽입된 객체의 ID가 무엇인지 어떻게 알 수 있을까 고민하여 사용해야 할 방법을 찾았습니다.flush
의 방법EntityManager
.
불행하게도 나는 그것을 받았습니다.
작업 클론 단위에 null 또는 0개의 기본 키가 있습니다.
위의 방법을 사용할 때는 예외입니다.문제는 제 데이터베이스가 모든 것을 가지고 있다는 것에 있다고 생각합니다.ID's
set on autoincrement (나는 ORACLE 11G Express를 사용한다), 그래서 그것을 커밋하기 전에null
가치와 그것이 트랜잭션을 롤백합니다.
어떻게 해야 고칠 수 있을까요?
이것은 DB(ID는 autoincrement[Sequences and Trigger 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 + " ]";
}
}
ID가 0(0)인 데이터베이스에 항목을 수동으로 추가했기 때문에 이런 일이 발생했습니다.제 경우에는 이클립스링크에서 ID를 0으로 처리할 수 없었습니다.그래서 persistence.xml에 다음을 추가했습니다.
<property name="eclipselink.allow-zero-id" value="true"/>
이 속성은 EclipseLink가 0을 유효한 ID로 처리하도록 합니다.
[1] http://meetrohan.blogspot.de/2011/11/eclipselink-null-primary-key.html
JPA가 ID를 자동으로 생성한다는 것을 알기 위해서는 @GeneratedValue로 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;
오라클을 통해 사용할 수 있습니다.GenerationType.IDENTITY
그리고.@SequenceGenerator
이 경우 시퀀스를 조회하고 ID를 채우기 위해 트리거가 필요하지 않을 경우 JPA가 이를 대신 수행합니다.잘 모르겠어요.GenerationType.AUTO
Oracle과 함께 작동하지만, 작동하는 경우 시퀀스를 쿼리하고 ID를 채우는 트리거가 필요합니다.GenerationType.TABLE
는 가장 휴대성이 뛰어난 솔루션으로, JPA에서 관리하는 독립 테이블을 사용하여 시퀀스를 저장하므로 모든 데이터베이스에서 작동합니다.
위 링크의 문서를 확인합니다.
말씀하신 것처럼, 문제는 거래를 실행해도 자동 증가 기능이 바로 실행되지 않는다는 데 있습니다.실제로 동일한 EntityManager와 데이터베이스 상호 작용을 관리하는 동안에는 그렇지 않습니다.제가 묻고 싶은 것은, 당신은 왜 고집을 부리느냐는 것이고, 그럼 당신은 그 거래를 어쨌든 실행에 옮기느냐는 것입니다.제가 보기엔 암호가 복제된 것 같네요.이거 플러시로 봐요.
언급URL : https://stackoverflow.com/questions/22026715/jpa-null-or-zero-primary-key-encountered-in-unit-of-work-clone
'programing' 카테고리의 다른 글
없는 경우 MySQL 추가 열 (0) | 2023.10.01 |
---|---|
카드뷰에 색 테두리를 추가하는 방법? (0) | 2023.10.01 |
MYSQL: 다음 업데이트 트리거가 작동하지 않는 이유는 무엇입니까? (0) | 2023.10.01 |
Jquery Ajax, mvc.net 컨트롤러에서 성공/오류 반환 (0) | 2023.10.01 |
CSS div 요소 - 가로 스크롤 막대만 표시하는 방법? (0) | 2023.09.26 |