queryFactory.select(Projections.bean(GetMyCommentResponse.MyCommentInfo.class, commentEntity.id.as("commentId"), commentEntity.content.as("content"), commentEntity.likeCount.as("likeCount"), commentEntity.createDateTime.as("createDateTime"), Projections.bean( GetMyCommentResponse.MyCommentedPopUpInfo.class, postEntity.id.as("postId"), postEntity.name.as("postName"), postEntity.mainImageUrl.as("mainImageUrl"), ).as("postInfo"), // commentEntity // 엔티티도 같이 조회하면 에러가 나지 않음 )) .from(commentEntity) .join(commentEntity.post, postEntity).fetchJoin() 안녕하세요 영한님! 강의 잘 듣고 있습니다. 공부 중에 코드를 작성하다 query specified join fetching, but the owner of the fetched association was not present in the select list 이런 에러가 발생했는데, fetchjoin시 실제 질의하는 대상 Entity를 select절에 쓰지않아서 에러가 나더라구요. select절에 commentEntity를 추가하면 에러가 발생하지 않지만 이미 commentEntity의 필드들은 모두 가져왔는데, 또 조회하는게 불필요한 작업이라고 생각되어서요. 그렇다고, fetchjoin이 아닌 일반 조인을 써버리면 코멘트마다 포스트에 대해서 n+1 문제가 발생할 것이라고 생각되구요 이러한 상황에서 좋은 해결방법이 있을까요? 감사합니다
강의하신 코드랑 같고 try { Team team = new Team(); team.setName("teamA"); em.persist(team); Member member = new Member(); member.setUsername("member"); member.setAge(10); member.setTeam(team); em.persist(member); em.flush(); em.clear(); String query = "select m from Member m left join m.team t"; List<Member> result = em.createQuery(query, Member.class) .getResultList(); tx.commit(); } catch (Exception e) { tx.rollback(); e.printStackTrace(); } finally { em.close(); } 결과 Hibernate: /* select m from Member m left join m.team t */ select m1_0.id, m1_0.age, m1_0.TEAM_ID, m1_0.username from Member m1_0 left join이 안나가네요, jpql로 join까지 썻는데 왜 안나가는걸까요
public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); try { Member member = new Member(); member.setUsername("A"); System.out.println("======================"); em.persist(member); Thread.sleep(9000); System.out.println("======================="); tx.commit(); } catch (Exception e) { tx.rollback(); } finally { em.close(); } emf.close(); } } @Entity public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name", nullable = false) private String username; public Member() { } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } } 우선 생각 했던 결과는 현재 identity 전략이므로 em.persist() 할 경우 insert 쿼리가 DB에 바로 보내지고 DB의 Member 테이블에 값이 저장되는거를 예상했습니다. 실제 실행해 보면 ====================== Hibernate: /* insert for jpa_basic.ex1_hello_jpa.hellojpa.Member */insert into Member (name, id) values (?, default) Thread.sleep(9000) 전까지는 insert 쿼리가 콘솔에 잘 찍힙니다. 그래서 H2 콘솔에 데이터가 잘 저장이 됐는지 확인 해봤습니다. 결과는 저장이 되지 않았습니다. Thread.sleep(9000)가 끝나고 나서야 데이터가 저장이 됩니다. 그래서 생각했던 결과인 identity 전략에서 em.persist() 할 경우 왜 DB에 바로 저장이 안되는건지 궁금합니다. 참고로 http://hibernate.hbm2ddl.auto 옵션은 create입니다. 감사합니다.
데이터 전처리 과정에서 이해되지 않는 부분이 있습니다. import pandas as pd import FinanceDataReader as fdr df_krx = fdr.StockListing('KRX') df_krx 로 데이터를 확인했습니다. ㄴ일부 컬럼 (ex.Dept)에 결측치가 있습니다. <- 값이 비어있습니다. Nan 값으로 채워진 것은 아닙니다. ㄴ이 때 info() 메소드와 df_krx.isnull()로 확인해보면 null값이 없는 것으로 나오고 isnull() 또한 모두 false가 나오는데 원인을 모르겠습니다. ㄴ이후 to_csv 메소드를 사용하여 파일을 저장한 후 저장한 파일을 읽어왔을 때는 해당 값들이 NaN 값으로 바뀌어 있는데요. 원인이 무엇일까요?
# warning 어쩌구 뜨면 쓰는건데 굳이 안써도 됨 import urllib3 urllib3.disable_warnings() # text None Type 에러 일 시 header를 추가해준다. # SSLdError 발생 시 verify옵션 추가해준다. header = { 'User-Agent' : 'Mozilla/5.0', 'Referer' : 'https://www.riss.kr/search/Search.do?isDetailSearch=N&searchGubun=true&viewYn=OP&queryText=&strQuery=%ED%8C%A8%EC%85%98+%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5&exQuery=&exQueryText=&order=%2FDESC&onHanja=false&strSort=RANK&p_year1=&p_year2=&iStartCount=0&orderBy=&mat_type=&mat_subtype=&fulltext_kind=&t_gubun=&learning_type=&ccl_code=&inside_outside=&fric_yn=&db_type=&image_yn=&gubun=&kdc=&ttsUseYn=&l_sub_code=&fsearchMethod=&sflag=1&isFDetailSearch=N&pageNumber=1&resultKeyword=%ED%8C%A8%EC%85%98+%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5&fsearchSort=&fsearchOrder=&limiterList=&limiterListText=&facetList=&facetListText=&fsearchDB=&icate=re_a_kor&colName=re_a_kor&pageScale=100&isTab=Y®nm=&dorg_storage=&language=&language_code=&clickKeyword=&relationKeyword=&query=%ED%8C%A8%EC%85%98+%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5' } for article in articles: title = article.select_one(".title > a").text link = 'https://www.riss.kr' + article.select_one(".title > a").attrs['href'] # 상세 페이지로 요청 response = requests.get(link, headers=header, verify=False) html = response.text soup = BeautifulSoup(html, 'html.parser') # 2. 순서를 기준으로 찾기 if soup.find('span', string='발행기관'): press = soup.find('span', string='발행기관').find_next_sibling().text # find_next_sibling 옆에 있는 명령어를 찾아라 라는 명령문 else: press = [] if soup.find('span', string='발행연도'): year = soup.find('span', string='발행연도').find_next_sibling().text else: year = [] if soup.find('span', string='주제어'): keywords = soup.find('span', string='주제어').find_next_sibling().text.split(';' '') keywords_result = [] for keyword_for in keywords: keywords_result.append(keyword_for.strip()) else: keywords = [] print(title, link, press, year, keywords_result) # result = [] # for keyword in keywords: # result.append(keyword.strip())
Member.java @OneToMany @JoinColumn(name="member") private List<Order> orders = new ArrayList<>(); Order.java @ManyToOne @JoinColumn(name="member_id") //맵핑할 컬럼 private Member member; Member 의 joinColumn 은 member 객체 자체이고 Order의 joinColumn은 db의 컬럼 명인데 member 의 joinColumn 을 member_id, 즉 db의 컬럼명으로 또는 그냥 id 라고 하면 안되나요? 안된다면 이유도 알려주시면 감사하겠습니다!!
수정, 삭제, 삽입 같은 경우에는 데이터 변경이라 영속성 컨텍스트의 쓰기 저장소에 보관되어 있다가 커밋 직전에 한번에 보내지는 반면 em.find()를 통해 발생하는 조회 쿼리는 find() 사용시 바로 디비에 전송이 되는건지 궁금합니다. em.find()를 통해 발생한 조회 쿼리는 트랜잭션 커밋 종료에 상관없이 디비에 바로바로 전송이 되는건지 궁금합니다.
DTO 쿼리 작성 시 join fetch 로 작성하는 경우는 에러가 발생하고 join 으로 작성하는 경우에는 에러가 발생하지 않았는데요. join fetch 의 개념은 결국 지연로딩을 작동시키지 않고 한 번에 연관된 것들 다 가져온다는 것인데 왜 여기선 안 되는 것인지 궁금합니다. 엔티티 @Query문하고 DTO @Query 테스트 코드를 돌렸는데 서로 영향을 미쳐 테스트가 실패라고 뜹니다. @Transactional 을 붙여 롤백이 되게끔 하여 해결은 했지만 궁금한 점이 있습니다. 스프링 데이터 JPA 테스트를 돌릴 때 @SpringBootTest 어노테이션 붙이면 자동으로 롤백이 되는 것이 아닌가요? package study.springdatajpa.repository; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; import study.springdatajpa.domain.Member; import study.springdatajpa.domain.Team; import study.springdatajpa.dto.MemberDto; import java.util.List; @SpringBootTest class MemberRepositoryTest { @Autowired private MemberRepository memberRepository; @Autowired private TeamRepository teamRepository; @Test @Transactional void testQuery() { Member m1 = new Member("AAA", 10); Member m2 = new Member("BBB", 20); memberRepository.save(m1); memberRepository.save(m2); List<Member> result = memberRepository.findUser("AAA", 10); Assertions.assertThat(result.get(0)).isEqualTo(m1); } @Test @Transactional void testDtoQuery() { Team team = new Team("teamA"); teamRepository.save(team); Member m1 = new Member("AAA", 10); Member m2 = new Member("BBB", 20); m1.setTeam(team); m2.setTeam(team); memberRepository.save(m1); memberRepository.save(m2); List<MemberDto> dtoList = memberRepository.findUserDto(); Assertions.assertThat(dtoList.size()).isEqualTo(2); } }