Java for Web 학습 노트(일일이):Entity 맵 만 들 기(4)동적 표 만 들 기
포획 표 에 존재 하지 않 는 이상
Connection 가 져 오기 Entity Manage 에서 Connection 을 가 져 올 수 있 는 지 는 JPA 의 구체 적 인 실현 에 의존 합 니 다.Eclipse 는 지원 하지만 Hibernate 는 지원 하지 않 습 니 다.
// unwrap , Hibernate
Connection conn = entityManager.unwrap(Connection.class);
// Hibernate api, unwrap() Hibernate session
Session session = entityManager.unwrap(Session.class);
이 길 은 통 하지 않 습 니 다.DataSource 에서 가 져 와 야 합 니 다.
표를 만 들 때 이상 을 던 집 니 다.
public class WantCreateTableException extends RuntimeException{
private static final long serialVersionUID = 1L;
public WantCreateTableException(String message) {
super(message);
}
}
창고 코드 수정
@Repository
@Validated
public class EventRepository {
private static final Logger log = LogManager.getLogger();
private static final Gson gson = new Gson();
@PersistenceContext private EntityManager entityManager;
@Inject private DataSource dataSource;
private static final String CREATE_TABLE_SQLFORMAT = "CREATE TABLE IF NOT EXISTS `%s`("
+ "`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,"
+ "`data` text,"
+ "PRIMARY KEY (`id`)"
+ ")ENGINE=InnoDB DEFAULT CHARSET=utf8";
public void createTable(String tableName){
String sql = String.format(CREATE_TABLE_SQLFORMAT, tableName);
try(Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);){
ps.execute();
}catch(SQLException e){
log.error("(SQL ERROR) Try to create table {} error : {}", tableName, e.toString());
}
}
private String getTableName(){
... ...
}
public EventData findOne(Long id) {
log.traceEntry();
String tableName = getTableName();
try{
String sql = String.format("SELECT * FROM `%s` WHERE `id`=?", tableName,id);
return EventData.build((EventEntity) entityManager.createNativeQuery(sql,EventEntity.class)
.setParameter(1, id).getSingleResult());
}catch(Exception e){
return null;
}
}
public void save(EventData event) {
try{
if(event.getId() == null || event.getId() == 0)
this.insert(event);
else
this.update(event);
}catch(Exception e){
if(isTableNotExist(e, getTableName()))
throw new WantCreateTableException(getTableName());
else
throw e;
}
}
private boolean update(EventData data) {
... ...
}
private void insert(EventData data) {
... ...
}
private boolean isTableNotExist(Exception e,String tableName){
if(e.getCause() == null || e.getCause().getCause() == null)
return false;
String message = e.getCause().getCause().getMessage();
return StringUtils.contains(message, tableName.concat("' doesn't exist"));
}
}
사용 예
@Service
public class TestService {
@Transactional
public void test2(){
EventData event = new EventData();
event.addData("Hello,world!");
this.eventRepository.save(event);
}
}
다음은 테스트 예 일 뿐 입 니 다.저 희 는 contrller 에서 창 고 를 호출 했 습 니 다.이렇게 하면 실제 적 으로 좋 지 않 습 니 다.contrller 는 Service 만 호출 해 야 합 니 다.저 희 는 중간 에 업무 논리 서 비 스 를 가지 고 TestService 를 호출 하여 관련 처 리 를 완성 할 수 있 습 니 다.@Transactional 은 Runtime Exception 을 만 날 때 사 무 를 종료 합 니 다.사 무 는 proxy 방식 을 사용 합 니 다.즉,이러한 내부 호출 은 역할 을 하지 않 습 니 다.
@Controller
public class TestController {
@Inject TestPageService testService;
@Inject EventRepository eventRepository;
private void mytest(){
try{
testService.test2();
}catch(WantCreateTableException e){
this.eventRepository.createTable(e.getMessage());
testService.test2();
}
}
}
나 는 아래 와 같이 쓰 려 고 시 도 했 지만 실패했다.
// , Transaction was marked for rollback only; cannot commit;
// WantCreateTableException , , hibernate rollback:
// : Servlet.service() for servlet [springWebDispatcher] in context with path [/chapter22] threw exception
// [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException:
// Transaction was marked for rollback only; cannot commit; nested exception is org.hibernate.TransactionException:
// Transaction was marked for rollback only; cannot commit] with root cause
@Transactional(noRollbackFor = WantCreateTableException.class)
public void test2(){
EventData event = new EventData();
event.addData("Hello,world!");
try{
this.eventRepository.save(event);
}catch(WantCreateTableException e){
this.eventRepository.createTable(e.getMessage());
this.eventRepository.save(event);
}
}
관련 링크:나의 Professional Java for Web Applications 관련 글
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA 객체 작성 및 제거 방법정적 공장 방법 정적 공장 방법의 장점 를 반환할 수 있습니다. 정적 공장 방법의 단점 류 공유되거나 보호된 구조기를 포함하지 않으면 이불류화할 수 없음 여러 개의 구조기 파라미터를 만났을 때 구축기를 고려해야 한다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.