728x90
반응형
728x90
반응형
728x90
반응형

jpa repository 메소드 사용시 에러가 나는 경우입니다.

원인은 엔티티에 없는 delYn 파라미터를 findByNameAndDelYn(String name) 와 같이 사용하려는 경우 발생합니다.

 

아래는 에러 전문

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.

20220228 11:16:35.550 [main] ERROR o.s.b.SpringApplication - Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bbsService': Unsatisfied dependency expressed through field 'repositoryClass'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bbsRepository' defined in packagename.core.model.repository.URepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List packagename.core.model.repository.Bbs.findByUrlLikeAndDelYn(java.lang.String)! Method public abstract java.util.List packagename.core.model.repository.Bbs.findByUrlLikeAndDelYn(java.lang.String) expects at least 2 arguments but only found 1. This leaves an operator of type SIMPLE_PROPERTY for property delYn unbound.

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)

at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)

at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944)

at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:917)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:582)

at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144)

at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767)

at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)

at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426)

at org.springframework.boot.SpringApplication.run(SpringApplication.java:326)

at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311)

at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300)

at packagename.BookKeepingApplication.main(BookKeepingApplication.java:12)

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bbsRepository' defined in packagename.core.model.repository.URepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List packagename.core.model.repository.Bbs.findByUrlLikeAndDelYn(java.lang.String)! Method public abstract java.util.List packagename.core.model.repository.Bbs.findByUrlLikeAndDelYn(java.lang.String) expects at least 2 arguments but only found 1. This leaves an operator of type SIMPLE_PROPERTY for property delYn unbound.

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)

at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)

at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)

... 21 common frames omitted

Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List packagename.core.model.repository.Bbs.findByUrlLikeAndDelYn(java.lang.String)! Method public abstract java.util.List packagename.core.model.repository.Bbs.findByUrlLikeAndDelYn(java.lang.String) expects at least 2 arguments but only found 1. This leaves an operator of type SIMPLE_PROPERTY for property delYn unbound.

at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.(PartTreeJpaQuery.java:96)

at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:107)

at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:218)

at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:81)

at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:100)

at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(QueryExecutorMethodInterceptor.java:93)

at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)

at java.util.Iterator.forEachRemaining(Unknown Source)

at java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Unknown Source)

at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)

at java.util.stream.AbstractPipeline.copyInto(Unknown Source)

at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)

at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)

at java.util.stream.AbstractPipeline.evaluate(Unknown Source)

at java.util.stream.ReferencePipeline.collect(Unknown Source)

at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.mapMethodsToQuery(QueryExecutorMethodInterceptor.java:95)

at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$new$0(QueryExecutorMethodInterceptor.java:85)

at java.util.Optional.map(Unknown Source)

at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.(QueryExecutorMethodInterceptor.java:85)

at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:303)

at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:323)

at org.springframework.data.util.Lazy.getNullable(Lazy.java:230)

at org.springframework.data.util.Lazy.get(Lazy.java:114)

at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:329)

at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:144)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782)

... 31 common frames omitted

Caused by: java.lang.IllegalStateException: Method public abstract java.util.List packagename.core.model.repository.Bbs.findByUrlLikeAndDelYn(java.lang.String) expects at least 2 arguments but only found 1. This leaves an operator of type SIMPLE_PROPERTY for property delYn unbound.

at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.throwExceptionOnArgumentMismatch(PartTreeJpaQuery.java:161)

at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.validate(PartTreeJpaQuery.java:147)

at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.(PartTreeJpaQuery.java:90)

... 57 common frames omitted

 

 

 

728x90
반응형
728x90
반응형

예전에 써봤지만 기억나지 않아 살짝 삽질한...

내가 기억하기 위해 남기는 메모.

.....

1. java코드 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* #### ReqDTO.java (DTO class) ####*/
public class ReqDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer dmnSeq;
    private String expt;
    private String prscYn;
    private String delYn;
}
 
/* #### Service.java #### */
List<ReqDTO> insertList = new ArrayList<>();
for () {
    // insert할 DTO를 작성함
}
// mapper 호출
Integer cnt = mapperClass.insertTable(insertList);
 
/* #### Mapper.java (interface) #### */
public Integer insertTable(List<ReqDTO> reqDTO) throws Exception;
 
cs

 

2. mybatis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<insert id="insertTable" parameterType="com.packagename.dto.ReqDTO">
    INSERT INTO TABLE_NAME
        (
        DMN_SEQ
        , EXPT
        , PRSC_YN
        , DEL_YN
        )
    VALUES
        <foreach collection="list" item="item" index="index" open="" separator=", " close="">
           (
           #{item.dmnSeq}
           , #{item.expt}
           , #{item.prscYn}
           , #{item.delYn}
           )
        </foreach>
</insert>
cs

 

728x90
반응형
728x90
반응형

ArrayList.remove()를 통해 List 특정항목을 제거해야 했다.

 

작성한 코드는 아래와 같았다.

1
2
3
4
5
6
7
8
9
10
11
List<Integer> delIndexList = new ArrayList<>();
/** 조건에 의해 삭제할 index를 delIndexList에 추가 **/
 
if (delIndexList != null && delIndexList.size() > 0) {
    // List에서 remove시 남은 요소들의 index가 변경되므로 2개 이상의 삭제시 문제 방지를 위해 
    // 삭제할 index를 가진 delIndexList를 역정렬하여 진행
    delIndexList = delIndexList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
    for (Integer index : delIndexList) {
        list.remove(index);
    }
}
cs

 

그러나 이상하게도 9번 라인에서 삭제가 되지 않는 것이다.

임의로 1을 넣어 진행해보니 문제가 없었다.

즉, ArrayList.remove(index)에서 index는 int 형으로 해야한다.

 

아쉽게도 integer를 사용해도 별 다른 에러는 나오지 않고 넘어가고 삭제되지 않아 처음에는 쉽게 원인을 인지하기 어렵다.

 

 

 

* 관련글

[java] ArrayList를 다룰때 흔한 실수 : https://deonggi.tistory.com/65

 

728x90
반응형
728x90
반응형

에디터에서 흔히 많이 사용되는 input 영역에 2개 이상의 태그를 작성하기 위한 기능이 필요했다.

jQuery에서 사용할 수 있는 plugin을 찾아보니 Suggestags 라는 것이 있어 사용하기로 했다.

 

* plugin file download : https://github.com/amsify42/jquery.amsify.suggestags

* 환경 : jQuery v3.5.1, Bootstrap v4.5.3 사용, Suggestags 1.27.0 적용

 

1. plugin 적용

1
2
<link rel="stylesheet" href="/css/amsify.suggestags.css">
<script src="/js/jquery.amsify.suggestags.js"></script>
cs

 

2. 적용할 태그

1
<input type="text" class="form-control" id="tagsTxt">
cs

 

3. 내 소스에 적용

3-1. 기본 가이드

plugin  가이드 : https://openbase.com/js/suggestags/documentation

javascript 객체 상수 (constant) : https://webclub.tistory.com/527

기본적인 사용방법은 해당 가이드를 사용하면 된다.

3-2. 내가 필요했던 기능

1) javascript로 태그를 전부 다른 값으로 변경해야 한다.

2) javascript로 태그를 하나 추가하고 싶다.

3) 태그가 변경될 시 callback 이벤트를 사용하고 싶다.

3-3. 기존 소스의 문제점

다만 3-2의 내용들을 사용하기 위해서 refresh를 사용했는데

이 경우 기존에 선언시 설정했던 정보가 모두 날아가는 문제가 있었다.

 

3-4. 그래서 아래와 같은 함수를 만들어 적용했다.

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// plugin 사용을 위한 값 세팅
definedValues();
// plugin 적용
usedSuggesTagsPlugin($('#tagsTxt'), 'init');
 
// 태그 전체 변경 변경시 
// tagsList : 'tag1,tag2' 형태의 스트링
usedSuggesTagsPlugin($('#tagsTxt'), 'setTags', {tags:tagsList});
 
// 태그 하나 추가 시
usedSuggesTagsPlugin($('#tagsTxt'), 'addTag', {tags:tag});
 
// javascript 객체 상수 (constant), 출처 : https://webclub.tistory.com/527
function definedValues(){
    constant.set('suggestagsSetting', {
        tagLimit : 10,                                      // 태그 최대 갯수 제한
        tags : '',                                          // 입력되는 태그 값
    });
}
 
/**
 * Suggestags의 사용을 위한 보조 함수
 * 출처 : https://openbase.com/js/suggestags/documentation
 * @param selector  : jquery형 selector
 * @param action    : 어떤 형태의 작업인지
 * => init : 사용을 위한 선언
 * => setTags : js로 태그 전체 변경시
 * => addTag : js로 태가 하나 추가시
 * => getClass : plugin에서 사용되는 클레스 값 전체를 구할때
 * @param value     : object형, action이 getClass인 경우 사용함
 * @returns
 */
function usedSuggesTagsPlugin(selector, action, value){
    if (isNull(selector))
        throw ': we need selector info for Suggestags plugin!';
    
    var objValue = !isNull(value) ?
            Object.assign(constant.get('suggestagsSetting'), value) 
            : constant.get('suggestagsSetting');
    
    // 선언시 세팅값 정의
    var objInit = {
            // 태그 반경시 callback 이벤트 설정
            afterAdd : function(e) {
                checkTagValuse();
            },
            afterRemove : function(e) {
                checkTagValuse();
            },
    };    
    if (!isNull(objValue) && !isNull(objValue.tagLimit) && Number(objValue.tagLimit) > 0) {
        Object.assign(objInit, {
            tagLimit: objValue.tagLimit
        });
    }
    
    // plugin 적용
    if (isNull(action) || action == 'init') {
        init();
        return;
    }
    
    if (!isNull(action) && (action == 'setTags' || action == 'addTag'
            && !isNull(objValue) && !isNull(objValue.tags)) {
        // refresh 사용시 tagLimit와 같은 기존 세팅 값이 초기화 되므로 재생성하도록 처리
        init();
        if (action == 'setTags') {
            var arrValue = objValue.tags.split(',');
            $.each(arrValue, function(i, e){
                amsifySuggestags.addTag(e.trim());
            });
            return;
        } else if (action == 'addTag') {
            amsifySuggestags.addTag(objValue.tags.trim());
            return;
        }
    } else if (!isNull(action) && action == 'setTags' 
        && !isNull(objValue) && isNull(objValue.tags)) {
        init();
        return;
    }
    
    /**
     * 사용예
     * 1. 아직 반영되지 않은 입력중인 태그 값을 구할때
     *  : $('input[class="'+usedSuggesTagsPlugin(selector, 'getClass').sTagsInput.substring(1)+'"]').val()
     */ 
    if(!isNull(action) && action == 'getClass') {
        amsifySuggestags = new AmsifySuggestags(selector);
        return amsifySuggestags.classes;
    }
    
    
    /* 내부함수 - 시작 */
    function init(){
        if (action != 'addTag') selector.val('');
        amsifySuggestags = new AmsifySuggestags(selector);
        amsifySuggestags.destroy();
        amsifySuggestags = new AmsifySuggestags(selector);
        amsifySuggestags._settings(objInit);
        amsifySuggestags._init();
    }
    
    // 태그 변경 시 이벤트 
    function checkTagValuse(){    
        // 입력된 태그 값을 비교하여 같거다 다른 경우 분기
    }
    /* 내부함수 - 끝 */
}
 
/**
 * param이 null, undefined, 공백 포함 빈 스트링인 경우 true, 값이 있는 경우 false
 * @param param
 */
function isNull(param){
    if(typeof param == "undefined" || param == null || param.length == 0
            || (typeof param == 'string' && (param == "" || param.trim().length == 0)))
        return true;
    else
        return false ;
}
cs

 

 

 

분명히 더 아름다운 방법이 있겠지만 우선 이렇게 마무리 했다.

(어후 삽질이야...)

 

728x90
반응형
728x90
반응형

모든 테이블에 session_id라는 컬럼(not null)을 추가하고, jpa entity에서 @PrePersist를 이용해 insert시 자동 작성하도록 설정 했다.

그리고 modelmapper에서 null인 값은 맵핑하지 않을꺼야 라고 생각하고 수정 시는 테스트 하지 않았다.

근데 왠걸... 내 소스는 맵핑 설정에 그런건 없다.

그래서 ...... 이렇게 삽질이 시작됐다.

 

내가 생각한 순서는 이러했다.

 

1. 맵핑에서 sessionId 파라미터는 맵핑하지 않는다.

insert시에는 @PrePersist에서 처리하니 문제가 없을 것이고, 수정 시에는 find한 값에 modelmapper로 맵핑하니 Bean에 설정을 추가하면 된다고 생각했다.

소스는 아래와 같다.

1
2
3
4
5
// GrpCodeReqDTO -> GroupCode 맵핑 시에만 사용됨
TypeMap<GrpCodeReqDTO, GroupCode> typeMap = modelMapper.createTypeMap(GrpCodeReqDTO.class, GroupCode.class);
typeMap.addMappings(mapping -> {
   mapping.skip(GroupCode::setSessionId);
});
cs

근데 이 소스의 문제점은 GrpCodeReqDTO -> GroupCode 맵핑 시에만 사용된다는 것이다.

공통으로 상속받은 BaseDTO(dto 공통상속), Base(entity 공통상속)를 사용하고 싶었지만 안 된다.

단순하게 간단하게 하고 싶은 나의 욕심과 달리 하나하나 클래스 별로해야 한다는 거다.

 

2. 차선책으로 값이 null인 경우 맵핑에서 스킵한다.

1
2
// 값이 널인 경우 스킵
modelMapper.getConfiguration().setSkipNullEnabled(true);
cs

1번이 안 되니 2번으로 만족해야 한다고 생각하고 수정을 마무리 하려고 했다.

 

 

그러다 번득든 생각!  jpa save에 대한 예외처리 방법이 있지 않을까?

3. jpa entity에서 updatable=false 추가

1
2
3
@Column(name = "SESSION_ID", nullable = false, updatable=false)
@ColumnDefault("NONE")
private String sessionId;
cs

insert를 위한 save시 제외를 원한다면 insertable=false,

update를 위한 save시 제외를 원한다면 updatable=false를 넣어주면 된다.

내 경우는 update시에만 해당되므로 updatable=false를 추가해서 해결했다.

 

 

 

이렇게 삽질을 마무리 했다.

그런데 ......

여기서 반전은 생성일, 생성자 컬럼에서 이미 아래와 같이 사용하고 있었다.

1
2
3
4
5
@Column(name = "CRT_DT", updatable = false)
protected Date crtDt;
 
@Column(name = "CRT_BY", updatable = false)
protected Integer crtBy;
cs

역시 모르고 막 사용하면 이런 삽질을 하는 거다!! ㅠ_ㅠ

 

 

 

* 참고한 글

 

ModelMapper 사용하기 – Deliwind

이번에는 java에서 내가 애용하는 modelMapper에 관해 글을 써보고자 한다. 엄청 유용한 라이브러리임에도 불구하고, 그래서 java 사용자는 모두들 사용하고 있을거라고 생각했는데, 생각보다 주위에

blog.deliwind.com

 

 

[JPA] 특정 칼럼을 제외하고 INSERT, UPDATE하는 방법

보통 JPA는 SAVE시에 모든 칼럼을 INSERT한다. 그럴 경우, NOT NULL로 설정된 칼럼은 기본값으로 삽입되는것이 아닌 NULL로 삽입을 시도한다. 이로 인해 에러가 발생하는데, 이럴 경우에 아예 쿼리에서

jobc.tistory.com

 

 

 

728x90
반응형
728x90
반응형

나는 개인 싱글서버로 웹서버를 개발중이다.

그런데 어제 스케줄 실행에서 로그를 기록하는 것을 서버에 적용한 후 스케줄이 중복 실행되는 걸 발견했다.

큰 이상을 유발할 수 있는 상황은 아니었으나 그래도 깔끔하지 못하니 수정하고 싶었다.

 

검색을 해보니 Tomcat, spring 설정의 문제를 확인해 보라는 내용이 있었지만, 내 경우는 적용할 수 가 없었다.

(이건 내 지식이 얕기 때문에 이해를 제대로 하지 못해 적용하지 못했을 것이다.)

 

추가로 검색을 해보니 멀티 서버의 경우에서 스케줄 중복을 방지하는 방법을 발견했다.

넓게 본다면 비슷한 의도로 중복실행 방지를 가능하게 처리하는 방법이 될 것으로 생각하고 적용 했으며, 잘 반영 되었다.

 

* 참고한 좋은글

 

ShedLock 사용하기

www.baeldung.com/shedlock-spring 같은 잡을 수행하는 각각 다른 서버에서의 인스턴스 A,B가 있을 때, A,B 둘 중 하나가 수행하도록, 2개 이상의 서버에서 중복 수행을 방지하도록 Lock 을 걸게 하는 라이브

eunbc-2020.tistory.com

 

 

* 내 서버 환경 : spring boot 2.4.3, 스케줄 적용 중

 

자세한건 위 글을 참고하시고, 내 기준에서 추가로 보강한 내용만 적는다.

 

1. 테이블 생성 (mysql)

1
2
3
4
5
6
7
8
CREATE TABLE IF NOT EXISTS `bookkeeping`.`SHEDLOCK` (
  `NAME` VARCHAR(64NOT NULL COMMENT '스케줄잠금이름',
  `LOCK_UNTIL` TIMESTAMP(3NULL COMMENT '잠금기간',
  `LOCKED_AT` TIMESTAMP(3NULL COMMENT '잠금일시',
  `LOCKED_BY` VARCHAR(255NULL COMMENT '잠금신청자',
  PRIMARY KEY (`NAME`))
ENGINE = InnoDB
COMMENT = '스케줄 잠금'
cs

 

2. Bean 주입

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
 
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
 
@Configuration
public class SchedulerConfig {
 
    @Bean
    public LockProvider lockProvider(JdbcTemplate dataSource) {
        return new JdbcTemplateLockProvider(dataSource);
    }
}
cs

 

이상.

오늘도 잘 해결해서 보람차다. ㅠㅠ 

 

 

3. 21.11.24 추가 이슈.

스케줄 실행시 언제나 에러가 난다는 것이다.

스케줄의 name 값으로 select를 먼저하고, 확인해서 insert, update로 분기해서 진행해야 하는데 무조건 insert 후 에러가 나면 update를 하는거다.(어쨌든 에러가 나도 실행은 잘 되긴 한다.)

하지만 이 excption이 눈에 거슬려서 고쳐보려 했지만 해결 방법을 아직 찾지는 못했다.

* 에러 전문

1. INSERT INTO shedlock(name, lock_until, locked_at, locked_by) VALUES('job_10min', '11/22/2021 12:28:00.003', '11/22/2021 12:20:00.050', 'DESKTOP-VMFC4B1')

{FAILED after 16 msec}

java.sql.SQLIntegrityConstraintViolationException: Duplicate entry 'job_10min' for key 'PRIMARY'

at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117)

at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1347)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025)

at net.sf.log4jdbc.sql.jdbcapi.PreparedStatementSpy.executeUpdate(PreparedStatementSpy.java:1080)

at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)

at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)

at org.springframework.jdbc.core.JdbcTemplate.lambda$update$2(JdbcTemplate.java:965)

at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:651)

at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:960)

at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:981)

at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:328)

at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:333)

at net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateStorageAccessor.lambda$insertRecord$0(JdbcTemplateStorageAccessor.java:65)

at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)

at net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateStorageAccessor.insertRecord(JdbcTemplateStorageAccessor.java:63)

at net.javacrumbs.shedlock.support.StorageBasedLockProvider.doLock(StorageBasedLockProvider.java:81)

at net.javacrumbs.shedlock.support.StorageBasedLockProvider.lock(StorageBasedLockProvider.java:65)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)

at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)

at com.sun.proxy.$Proxy61.lock(Unknown Source)

at net.javacrumbs.shedlock.core.DefaultLockingTaskExecutor.executeWithLock(DefaultLockingTaskExecutor.java:63)

at net.javacrumbs.shedlock.spring.aop.MethodProxyScheduledLockAdvisor$LockingInterceptor.invoke(MethodProxyScheduledLockAdvisor.java:85)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)

at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)

at packageName.core.schedule.cron.ScheduleCron$$EnhancerBySpringCGLIB$$5253d941.job_10min()

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)

at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)

at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95)

at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.util.concurrent.FutureTask.run(Unknown Source)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

 

 

 

728x90
반응형
728x90
반응형

mysql 사용시 종종 겪을 수 있는 문제입니다.

해당 문제는 문법적인 에러이고, 아래 에러문에서 해당되는 문제는 condition 이라는 컬럼명을 사용했기 때문입니다.

 

 

* 에러 전문

20211108 14:20:51.623 [http-nio-8091-exec-6] ERROR j.sqltiming - com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)

1. insert into table_name (crt_by, crt_dt, del_by, del_dt, del_yn, upd_by, upd_dt, condition, menu_seq, model_nm) values (0, '11/08/2021 14:20:51.585', NULL, NULL, 'N', 0, '11/08/2021 14:20:51.585', 'Y', 57, 'AAAA')

{FAILED after 16 msec}

java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'condition, menu_seq, model_nm) values (0, '2021-11-08 14:20:51.585', null, null,' at line 1

at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)

at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1347)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025)

at net.sf.log4jdbc.sql.jdbcapi.PreparedStatementSpy.executeUpdate(PreparedStatementSpy.java:1080)

at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)

at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)

at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)

at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57)

at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:43)

at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3200)

at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3806)

at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:84)

at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645)

at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282)

at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263)

at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317)

at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330)

at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287)

at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)

at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123)

at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185)

at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128)

at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55)

at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93)

at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:720)

at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:706)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362)

at com.sun.proxy.$Proxy89.persist(Unknown Source)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311)

at com.sun.proxy.$Proxy89.persist(Unknown Source)

at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:557)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)

at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)

at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)

at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:524)

at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)

at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:531)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:156)

at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:131)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)

at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)

at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)

at com.sun.proxy.$Proxy154.save(Unknown Source)

at packageName.front.webtools.service.WebtoolsService.insert(WebtoolsService.java:146)

at packageName.front.webtools.web.Controller.insert(Controller.java:71)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)

at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)

at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)

at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)

at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060)

at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)

at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)

at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)

at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)

at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)

at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)

at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

at java.lang.Thread.run(Unknown Source)

20211108 14:20:51.625 [http-nio-8091-exec-6] WARN o.h.e.j.s.SqlExceptionHelper - SQL Error: 1064, SQLState: 42000

20211108 14:20:51.625 [http-nio-8091-exec-6] ERROR o.h.e.j.s.SqlExceptionHelper - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'condition, menu_seq, model_nm) values (0, '2021-11-08 14:20:51.585', null, null,' at line 1

20211108 14:20:51.646 [http-nio-8091-exec-6] ERROR c.d.b.c.a.ExceptionControllerAdvice -

org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement

at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)

at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)

at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)

at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)

at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)

at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)

at com.sun.proxy.$Proxy154.save(Unknown Source)

at packageName.front.webtools.service.WebtoolsService.insert(WebtoolsService.java:146)

at packageName.front.webtools.web.Controller.insert(Controller.java:71)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)

at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)

at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)

at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)

at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060)

at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)

at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)

at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)

at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)

at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)

at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)

at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

at java.lang.Thread.run(Unknown Source)

Caused by: org.hibernate.exception.SQLGrammarException: could not execute statement

at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)

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.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)

at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)

at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57)

at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:43)

at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3200)

at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3806)

at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:84)

at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645)

at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282)

at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263)

at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317)

at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330)

at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287)

at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)

at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123)

at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185)

at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128)

at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55)

at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93)

at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:720)

at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:706)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362)

at com.sun.proxy.$Proxy89.persist(Unknown Source)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311)

at com.sun.proxy.$Proxy89.persist(Unknown Source)

at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:557)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)

at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)

at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)

at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:524)

at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)

at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:531)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:156)

at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:131)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)

at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)

at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)

... 59 more

Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'condition, menu_seq, model_nm) values (0, '2021-11-08 14:20:51.585', null, null,' at line 1

at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)

at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1347)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025)

at net.sf.log4jdbc.sql.jdbcapi.PreparedStatementSpy.executeUpdate(PreparedStatementSpy.java:1080)

at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)

at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)

at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)

... 112 more

- userMessage: null

- systemMessage: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement

- httpStatus: 500 INTERNAL_SERVER_ERROR

- code: null

 

 

 

 

 

728x90
반응형
728x90
반응형

검색엔진에서 내 사이트를 잘 찾게 만들기 위해서는 sitemap.xml, robots.txt가 필요하다.

내가 원했던건 컨트롤러에 의해 자동 생성된 것으로 리턴하는 것이다.

 

자동 생성하는 것은 아래 두개의 링크를 참고 했다.

 

[Spring] 스프링에서 sitemap.xml 및 robots.txt 처리하기

스프링 프레임워크로 사이트를 개발하여 sitemap 및 robots.txt 를 처리해야할 필요가 있을때 아래처럼 구성하면 유기적으로 관리가 가능합니다. sitemap.xml 에 신규 컨텐츠를 지속적으로 추가해주어

mytalkhome.tistory.com

 

spring boot sitemap 생성하기

참고  - site map 설명 링크 코드  - 참고 링크 @RestController public class TestController { @Autowired private RequestMappingHandlerMapping re; @GetMapping("/sitemap.xml") public String getSitemap(..

blog.eomsh.com

 

다만 이걸 적용 후 몇가지 문제가 있었다.

 

1. 최상단 태그가 ns2:urlset로 나왔다.

(이건 해결하고 검색엔진에 반영했기 때문에 실제 검색엔진에서 문제가 되는지 확인되지 않음.)

 

Build sitemap.xml by Java Spring

I'm building a sitemap.xml by Spring MVC @XmlRootElement(name = "urlset") public class XmlUrlSet{ @XmlElements(@XmlElement(name = "url", type = XmlUrl.class)) private List sitemap = ...

stackoverflow.com

위 링크의 정보를 따라서 적용하다보면 package-info.java를 추가 하라고 하는데 방법을 알 수 없었다.

추가하는 방법은 아래 링크 참고

 

팩키지 설명을 위한 package-info.java 파일 (v0.10)

팩키지 설명을 위한 package-info.java 파일

‘package-info.java’가 뭐야?

기본 Checkstyle 설정을 사용했더니 자바 파일마다 상단에 ‘Missing packag

 

egloos.zum.com

 

2. 구글 검색에서 sitemap 제출 시 에러 : 사이트맵을 읽을 수 있지만 오류가 있습니다. 지원하지 않는 파일 포맷

 

사이트맵을 읽을 수 있지만 오류가 있습니다. Sitemap이 HTML입니다. 라는 오류가 계속 뜹니다. 도와

 

support.google.com

 

답변 내용을 읽어보면 아래 링크에서 검사해 보면 원인을 찾아준다는 내용 이었다.

https://www.xml-sitemaps.com/validate-xml-sitemap.html

 

내 경우 검사해 본 결과 header의 content-type이 application/xml로 되어야 한다는 것 이었고, 

크롬에서 header 정보를 확인하는 방법은 아래 링크를 참조하자.

 

크롬에서 request, response header 확인하기.

1. 크롬에서 개발자도구를 시작해서 (F12를 누르면 열림) 2. Network 탭으로 이동합니다. 3. F5또는 Ctrl+R을 통해서 페이지를 새로고침합니다. 4. 그러면 name에 페이지요청 목록이 나오는데 원하는 것

paulaner80.tistory.com

그래서 결과적으로 컨트롤러에 produces = "application/xml;" 를 추가하여 sitemap.xml을 재출할 수 있었다.

728x90
반응형

+ Recent posts