programing

JPA Null 또는 0 기본 키가 워크 클론 단위에 있습니다.

oldcodes 2023. 10. 1. 21:55
반응형

JPA Null 또는 0 기본 키가 워크 클론 단위에 있습니다.

나는 에 대해 배웁니다.JPA데이터베이스를 만들고 거기에 몇 가지 값을 삽입하는 작업을 했습니다.최근에 삽입된 객체의 ID가 무엇인지 어떻게 알 수 있을까 고민하여 사용해야 할 방법을 찾았습니다.flush의 방법EntityManager.

불행하게도 나는 그것을 받았습니다.

작업 클론 단위에 null 또는 0개의 기본 키가 있습니다.

위의 방법을 사용할 때는 예외입니다.문제는 제 데이터베이스가 모든 것을 가지고 있다는 것에 있다고 생각합니다.ID'sset 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.AUTOOracle과 함께 작동하지만, 작동하는 경우 시퀀스를 쿼리하고 ID를 채우는 트리거가 필요합니다.GenerationType.TABLE는 가장 휴대성이 뛰어난 솔루션으로, JPA에서 관리하는 독립 테이블을 사용하여 시퀀스를 저장하므로 모든 데이터베이스에서 작동합니다.

위 링크의 문서를 확인합니다.

말씀하신 것처럼, 문제는 거래를 실행해도 자동 증가 기능이 바로 실행되지 않는다는 데 있습니다.실제로 동일한 EntityManager와 데이터베이스 상호 작용을 관리하는 동안에는 그렇지 않습니다.제가 묻고 싶은 것은, 당신은 왜 고집을 부리느냐는 것이고, 그럼 당신은 그 거래를 어쨌든 실행에 옮기느냐는 것입니다.제가 보기엔 암호가 복제된 것 같네요.이거 플러시로 봐요.

언급URL : https://stackoverflow.com/questions/22026715/jpa-null-or-zero-primary-key-encountered-in-unit-of-work-clone

반응형