👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Main {
    public static void main(String[] args) {
 
        // 생략
 
        try {
            Child child1 = new Child();
            Child child2 = new Child();
 
            Parent parent = new Parent();
            parent.addChild(child1);
            parent.addChild(child2);
 
            em.persist(parent);
            em.persist(child1);
            em.persist(child2);
 
            em.flush();
            em.clear();
 
            Parent findParent = em.find(Parent.class, parent.getId());
            em.remove(findParent);
 
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
            e.printStackTrace();
        } finally {
            em.close();
        }
 
        emf.close();
 
    }
 
}
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
ERROR: Referential integrity constraint violation: "FKLH67J1N7X7GT59U0PBKWQH6O6: PUBLIC.CHILD FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.PARENT(ID) (1)"; SQL statement:
/* delete jpa_basic.Parent */ delete from Parent where id=? [23503-200]
javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)
    at jpa_basic.Main.main(Main.java:446)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute batch
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:65)
    ... 2 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute batch
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:109)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:129)
    at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:105)
    at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:148)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:198)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:633)
    at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
    at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1352)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:443)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3202)
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2370)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
    ... 1 more
Caused by: org.h2.jdbc.JdbcBatchUpdateException: Referential integrity constraint violation: "FKLH67J1N7X7GT59U0PBKWQH6O6: PUBLIC.CHILD FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.PARENT(ID) (1)"; SQL statement:
/* delete jpa_basic.Parent */ delete from Parent where id=? [23503-200]
    at org.h2.jdbc.JdbcPreparedStatement.executeBatch(JdbcPreparedStatement.java:1235)
    at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:119)
    ... 20 more
 
 

 

 

📡 원인

Parent 객체를 삭제하려고 했으나, 외래키 제약 조건에 의해서 오류 발생

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Entity
public class Parent {
 
    @Id @GeneratedValue
    private long id;
 
    private String name;
 
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    private List<Child> children = new ArrayList<>();
 
    public void addChild(Child child){
        children.add(child);
        child.setParent(this);
    }
 
    public long getId() {
        return id;
    }
 
    public void setId(long id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public List<Child> getChildren() {
        return children;
    }
 
    public void setChildren(List<Child> children) {
        this.children = children;
    }
}
 
 

CascadeType.All을 선언하여, Parent 객체 삭제 시, Child도 함께 삭제

 

 

🖨️ 실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Hibernate: 
    /* delete jpa_basic.Child */ delete 
        from
            Child 
        where
            id=?
 
Hibernate: 
    /* delete jpa_basic.Child */ delete 
        from
            Child 
        where
            id=?
 
Hibernate: 
    /* delete jpa_basic.Parent */ delete 
        from
            Parent 
        where
            id=?
 
 

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import javax.persistence.*;
import java.util.List;
 
@Entity
public class Tmp {
 
    @Id @GeneratedValue
    @Column(name = "TMP_ID")
    private Long id;
 
    @OneToMany(mappedBy = "temp")
    private List<TmpItem> tmpItems;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public List<TmpItem> getTmpItems() {
        return tmpItems;
    }
 
    public void setTmpItems(List<TmpItem> tmpItems) {
        this.tmpItems = tmpItems;
    }
}
 
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Exception in thread "main" org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: jpabook.jpashop.domain.TmpItem.temp in jpabook.jpashop.domain.Tmp.tmpItems
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:844)
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:795)
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:53)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1693)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1661)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:286)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1214)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1245)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at jpabook.jpashop.JpaMain.main(JpaMain.java:15)
 
 
 

 

 

📡 원인

@OneToMany에서 매핑되는 TmpItem Entity에서 참조할 필드가 없음

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import javax.persistence.*;
import java.util.List;
 
@Entity
public class Tmp {
 
    @Id @GeneratedValue
    @Column(name = "TMP_ID")
    private Long id;
 
    @OneToMany(mappedBy = "tmp")
    private List<TmpItem> tmpItems;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public List<TmpItem> getTmpItems() {
        return tmpItems;
    }
 
    public void setTmpItems(List<TmpItem> tmpItems) {
        this.tmpItems = tmpItems;
    }
}
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import javax.persistence.*;
 
@Entity
public class TmpItem {
 
    @Id
    @GeneratedValue
    @Column(name = "TMP_ITEM_ID")
    private Long id;
 
    @ManyToOne
    @JoinColumn(name = "TMP_ID")
    private Tmp tmp;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public Tmp getTmp() {
        return tmp;
    }
 
    public void setTmp(Tmp tmp) {
        this.tmp = tmp;
    }
}
 
 
 

 

TmpItem Entity에 매핑된 필드와 동일한 이름으로 변경

     - @OneToMany(mappedBy = "temp") ▶ @OneToMany(mappedBy = "tmp")

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import javax.persistence.*;
import java.util.List;
 
@Entity
public class Tmp {
 
    @GeneratedValue
    @Column(name = "TMP_ID")
    private Long id;
 
    @OneToMany(mappedBy = "tmp")
    private List<TmpItem> tmpItems;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public List<TmpItem> getTmpItems() {
        return tmpItems;
    }
 
    public void setTmpItems(List<TmpItem> tmpItems) {
        this.tmpItems = tmpItems;
    }
}
 
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Exception in thread "main" org.hibernate.AnnotationException: No identifier specified for entity: jpabook.jpashop.domain.Tmp
    at org.hibernate.cfg.InheritanceState.determineDefaultAccessType(InheritanceState.java:266)
    at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:211)
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:781)
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:254)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:230)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:273)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1214)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1245)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at jpabook.jpashop.JpaMain.main(JpaMain.java:15)
 
 
 

 

 

📡 원인

Entity 선언 시, 필수적으로 @Id를 통해서 PK 1개 이상 지정해야 함

⭐ 데이터베이스 무결성 - 키 무결성

    - [CS] Database

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import javax.persistence.*;
import java.util.List;
 
@Entity
public class Tmp {
 
    @Id @GeneratedValue
    @Column(name = "TMP_ID")
    private Long id;
 
    @OneToMany(mappedBy = "tmp")
    private List<TmpItem> tmpItems;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public List<TmpItem> getTmpItems() {
        return tmpItems;
    }
 
    public void setTmpItems(List<TmpItem> tmpItems) {
        this.tmpItems = tmpItems;
    }
}
 
 
 

PK에 @Id 추가

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import javax.persistence.*;
import java.util.List;
 
public class Tmp {
 
    @Id @GeneratedValue
    @Column(name = "TMP_ID")
    private Long id;
 
    @OneToMany(mappedBy = "tmp")
    private List<TmpItem> tmpItems;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public List<TmpItem> getTmpItems() {
        return tmpItems;
    }
 
    public void setTmpItems(List<TmpItem> tmpItems) {
        this.tmpItems = tmpItems;
    }
}
 
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
Exception in thread "main" org.hibernate.AnnotationException: @OneToOne or @ManyToOne on jpabook.jpashop.domain.TmpItem.tmp references an unknown entity: jpabook.jpashop.domain.Tmp
    at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:97)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1823)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1767)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1655)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:286)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1214)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1245)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at jpabook.jpashop.JpaMain.main(JpaMain.java:15)
 
 
 

 

 

📡 원인

Entity 클래스 선언 시, @Entity 선언을 하지 않아 인식되지 않음

그에 따라 Entity간 매핑해놓은 @ManyToOne에서 unknown entity exception 발생

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import javax.persistence.*;
import java.util.List;
 
@Entity
public class Tmp {
 
    @Id @GeneratedValue
    @Column(name = "TMP_ID")
    private Long id;
 
    @OneToMany(mappedBy = "tmp")
    private List<TmpItem> tmpItems;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public List<TmpItem> getTmpItems() {
        return tmpItems;
    }
 
    public void setTmpItems(List<TmpItem> tmpItems) {
        this.tmpItems = tmpItems;
    }
}
 
 
 

Entity 클래스에 @Entity 추가

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
@Entity
@SequenceGenerator(
       name = "MEMBER_SEQ_GENERATOR",
       sequenceName = "MEMBER_SEQ",
       allocationSize = 3
)
public class Member {
 
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
    private Long id;
}
 
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: hello] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1326)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1252)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at jpa_basic.Main.main(Main.java:13)
Caused by:      [entity-name=jpa_basic.Member]
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:124)
    at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:344)
    at org.hibernate.internal.SessionFactoryImpl.lambda$new$1(SessionFactoryImpl.java:286)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1692)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:285)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:468)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1249)
    ... 4 more
Caused by: org.hibernate.MappingException: The increment size of the [MEMBER_SEQ] sequence is set to [3] in the entity mapping while the associated database sequence increment size is [5].
    at org.hibernate.id.enhanced.SequenceStyleGenerator.configure(SequenceStyleGenerator.java:261)
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:118)
 
 
 

 

 

📡 원인

SequenceGenerator에서 allocationSize를 5로 설정한 후, 3으로 수정

 

엔티티 매핑에서 MEMBER_SEQ 시퀀스의 증가 크기를 3으로 설정했지만,

실제 데이터베이스의 MEMBER_SEQ 시퀀스는 증가 크기가 5로 설정되어 있음

 

JPA DDL 생성 기능에서 value를 create로 설정하더라도 table처럼 Sequence 객체도 drop 후 새롭게 생성되지 않음

 

 

📰 해결 방법

1
2
DROP SEQUENCE IF EXISTS sequence_name;
 
 
 

DB에서 직접 drop 후 애플리케이션을 새롭게 실행해야 함