JAVA/spring

[1028 from 스프링 백기선 JPA]Hibernate _ 엔티티, Cascade, Fetch, Query FROM EntityManager

ERROR1.  

error creating bean with name 'entitymanagerfactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/hibernatejpaconfiguration.class]: invocation of init method failed; nested exception is org.hibernate.service.spi.serviceexception: unable to create requested service [org.hibernate.engine.jdbc.env.spi.jdbcenvironment]

두번째 서버 올렸을 때 postgresql 서버가 내려가있다는 메시지 와서 도커 재시작 해결. 

 


JPA 에서 EntityManager   

@Entity “엔티티”는 객체 세상 릴레이션. 
보통 클래스와 같은 이름을 사용하기 때문에 값을 변경하지 않음.
엔티티의 이름은 JQL에서 쓰임.
@Entity(name="myAccount")
@Table
public class Account
...기존 postgres 에서 user 가 키워드여서 user 테이블 사용불가 syntax에러 or. Entity 변경 사용  
@Table “릴레이션" 세상에서 엔티티
@Entity의 이름이 default .
테이블의 이름은 SQL에서 쓰임.
@Id 엔티티의 주키를 맵핑할 때 사용.
자바의 모든 primitive 타입과 그 랩퍼 타입을 사용할 수 있음_ 임의값과 구별과능 
-Date랑 BigDecimal, BigInteger도 사용 가능.
복합키를 만드는 맵핑하는 방법도 있지만 그건 논외로..
@GeneratedValue 주키의 생성 방법을 맵핑하는 애노테이션
생성 전략과 생성기를 설정할 수 있다.
- 기본 전략은 AUTO: DB 에따라 기본값 다름 postgres 시퀀스(생성전략다름, 명시가능 strategy)
-
TABLE, SEQUENCE, IDENTITY 중 하나.
@Column unique
nullable    : default true
length
columnDefinition
@Temporal 날짜데이터
현재 JPA 2.1까지는 Date와 Calendar만 지원.
@Transient 데이터 컬럼으로 맵핑하고 싶지 않은 멤버 변수에 사용.
application.properties spring.jpa.show-sql=true

spring.jpa.properties.hibernate.format_sql=true   // 보기좋게 포멧

Value 타입 종류 기본 : String, Date, Boolean..
Composite Value 타입
Collection Value 타입- 기본타입 콜렉션, 컴포짓 타입 콜렉션
<
Composite Value 타입 맵핑 @Embeddable
@Embedded
@AttributeOverrides
@AttributeOverride
Entity 타입
Value 타입
@Entity
public class Account{    >> 엔티티타입
    @Embedded
    private Address address ;      >>> 벨류타입.........Account 엔티티 통해서 접근. 
    @Embedded
    @Attribute
    private Address homeAddress ;
}
@Embeddable @Embeddable   > 새로운 타입값 지정. 
public class Address{
    private String street;
    private String etc;
}

    @Embedded
    @AttributeOverrides({   >> 새로운 타입값에 일부 변경
            @AttributeOverride(name = "etc", column = @Column(name = "etc2"))
    })
    private Address address;

1대다 단방향_@ManyToOne public class Study {
    @ManyToOne
    private Account one;   >> Study 가 주인._ 관계 값을 정의 위치. 
1대다 단방향
_@OneToMany
many 로 끝나야 컬렉션. >> account_studies 에 관계값 정의 
public class Account {
    @OneToMany
    private Set<Study> studies;

1대다 양방향 public class Account {
    @OneToMany(mappedBy = "owner")
    private Set<Study> studies = new HashSet<>();
public class Study {
    @ManyToOne                             >>> 이쪽에 관계값 정의 
    private Account owner;

소스작성
account.getStudies().add(study);
study.setOwner(account);
Session session = entityManager.unwrap(Session.class);
session.save(study);
session.save(account);
엔티티 상태 변화 -new Object()->  Transient: JPA가 모르는 상태

(from Transient )-session.save()-> Persistent: JPA가 관리중 상태
(fromDetached)-session.update()
                        session.marge();
                        session.saveOrUpdate()-> Persistent
Persistent: (1차 캐시, Dirty Checking, Write Behind, ...) : 변경사항 계속 모니터링
session.get()
session.load()
Query.Iterate()

(from Persistent) ->session.evict();  
                           session.clear();

                            session.close(); ->Detached: JPA가 더이상 관리하지 않는 상태.



-session.delete();->Removed: JPA가 관리하긴 하지만 삭제하기로 한 상태.
Cascade - @ManyToOne 엔티티 상태값 전이: 부모자식관계.에 쓰는 것을 추천.   
class Post{
@OneToMany(mappedBy = "post", cascade = CascadeType.PERSIST)
 private Comment comment;
}
post만 저장해도 comment 도 같이 저장.
cascade = {CascadeType.PERSIST, CascadeType.REMOVE}) 
cascade = CascadeType.All
Dirty Checking 상태변경 검사
(영속-managed-상태, Transaction 엔티티변경T@Transactional, Entity Transaction.  경우)
1) 엔티티 메니저에서 수정에 해당하는 부분에 더티 체킹 지원
2) 엔티티 데이터 변경부분 체크 DB 반영 
* 데이터 변경 시점: transaction commit, Entitymanager flush, jpql 사용시점
import org.hibernate.Session
Session session = entityManager.unwrap(Session.class);//jpa감싸는 hibernate api 그대로이용
session.save(study); session.save(account); 

Account k = session.load(Account.class, account.getId());   // null 일때 예외 
// session.get(Post.calss, 4l);  null 일 때null 가져옴

k.setUsername("ddd");
k.setUsername("eee");
System.out.println(k.getUsername());
Write Behind
DB 엔티티 변경사항을 최대한 필요한 시점에 반영하는것.
@DynamicUpdate 변경된 필드만 저장
Fetch *성능영향 연관 관계의 엔티티를 어떻게 가져올 것이냐... 지금 (Eager)? 나중에(Lazy)?
@OneToMany의 기본값은 Lazy
post 조회시 comment 를 가져오지 않음
@ManyToOne의 기본값은 Eager
comment 조회시 post 를 가져옴. 
Query JPQL, Criteria, Native Query 가 있다. 
JPQL (= HQL)  Java Persistence Query Language / Hivernate Query Language
데이터베이스 테이블이 아닌 엔티티 객체 모델 기반으로 쿼리 작성
JPA 하이버네이트가 해당쿼리 SQL로 변환 실행 , 타입세이프 하지 안음
TypedQuery<Post> query                                     // 지정해준 타입으로 나옴
= entityManager.
createQuery("SELECT p FROM Post As p", Post.class);  
List<Post> posts = query.getResultList();
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#hql
Criteria 타입 세이프 관리
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery criteria = builder.createQuery(Post.class);
Root root = criteria.from(Post.class);
criteria.select(root);
List posts = entityManager.createQuery(criteria).getResultList();
Native Query SQL 쿼리 실행
List<Post> posts = entityManager .createNativeQuery("SELECT * FROM Post", Post.class) .getResultList();

Composite    합성의 ... 컴포짓한 벨류타입. 

Transient   일시적인, 순간적인, 단기체류의  트랜지언트 

evict         쫓아내다. 이빅트

Detached   분리됨

캐쉬가 되었다. - PersistentContext 에 넣음. 

영향이 있는 테이블만 삭제하고 다시만듬

Model . getter setter 안만들어도 됨. 

Eager 열심인

Lazy  게으른

Criteria  criterion기준 복수  크리테리아.