728x90
반응형
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
반응형

모든 테이블에 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
반응형

특정 url을 특정서버 예를들면 운영서버에서는 사용하고 싶지 않았다.

하지만 그렇다고 주석처리는 싫다! 왜냐하면 그때 그때 주석처리를 하고 안하고 하면 실수가 있기 때문이다.

 

그래서 생각한 것은 아래와 같다.

1. application.properties의 값을 이용해 on/off 하는 방법을 찾는다.

2. 기존에 테스트서버와 운영서버 war를 동일한 파일로 했었는데 파일명을 다르게 하여 구분한다.

 

내 개발환경은 간단하게 아래와 같다.

1. spring boot 2.4.3

2. java 1.8

3. gradle 6.8.3

 

이제부터 적용한 내용이다!

시작하기에 앞서 application.properties는 서버별로 분리되어야 한다. (아래 링크 참조)

 

spring boot profile 설정 파일을 분리해 봅시다.

 spring으로 crud 하기 전에, 필요한 지식들을 먼저 보고 가겠습니다. spring boot 프로젝트를 보면, 왠 properties 파일들을 보게 됩니다. 이들은, 셋팅 파일인데요. 환경에 따라서, 이 값을 다르게 하고

codingdog.tistory.com

 

1. Controller 활성화, 비활성화 : @ConditionalOnExpression

 

Can a spring boot @RestController be enabled/disabled using properties?

Given a "standard" spring boot application with a @RestController, eg @RestController @RequestMapping(value = "foo", produces = "application/json;charset=UTF-8") public class MyController { @

stackoverflow.com

 

내가 적용한 샘플은 아래와 같다.

1) Controller에 @ConditionalOnExpression 사용 (4번라인)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 
@ResController
@ConditionalOnExpression("${my.controller.enabled:false}")
public class SampleContoroller {
    
    @GetMapping(value = "/callUrl1")
    public String call1() {
        ....
    }
 
    @GetMapping(value = "/callUrl2")
    public String call2() {
        ....
    }
    
}
 
cs

2) 각각의 application.properties에 필요에 따라 my.controller.enabled 값 설정

1
2
# controller enabled/disabled : true/false or remove
my.controller.enabled=true
cs

이렇게 하면 설정에 맞춰 해당 컨트롤러를 활성화 할 수 있다.

 

2. war 파일 배포시 실수를 줄이기 위해 테스트서버, 운영서버 용 파일을 구분한다.

이것을 위해 application.properties의 spring.profiles.active 값을 build.gradle에서 읽어 war 파일명에 넣어 해결한다.

 

How to use spring properties in gradle.build?

How can I use properties configured in resources/application.properties in gradle.build? I would like to get something like this : flyway { url = MAP_WITH_PROPERTIES['spring.datasource.url'] ...

stackoverflow.com

 

1) build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// read application.properties values
import java.util.Properties
def props = new Properties()
file('src/main/resources/application.properties').withInputStream {
    props.load(it)
}
def active = props['spring.profiles.active']
 
....
 
// war file name custom
version = '0.0.1-SNAPSHOT' +'-' + active
 
....
cs

 

이렇게 함으로서 의도했던 내용을 모두 반영했다.

 

추가로, timestemp를 war 파일명에 넣기

 

Add a time stamp to the JAR file name in Gradle

Java, gradle, jar

linuxtut.com

 

 

728x90
반응형
728x90
반응형

jpa 사용 중 발생된 에러로 오타에 의한 것이다.

 

Entity : Bbs

Repository : BbsRepository

문제가 되는 메소드 : findbyBbsSeqAndShowYnAndDelYn => findByBbsSeqAndShowYnAndDelYn 로 수정하여 해결

 

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

20210915 12:20:13.036 [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.BbsRepository 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.BbsRepository.findbyBbsSeqAndShowYnAndDelYn(java.lang.Integer,java.lang.String,java.lang.String)! No property findbyBbsSeq found for type Bbs!

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.BbsRepository 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.BbsRepository.findbyBbsSeqAndShowYnAndDelYn(java.lang.Integer,java.lang.String,java.lang.String)! No property findbyBbsSeq found for type Bbs!

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.BbsRepository.findbyBbsSeqAndShowYnAndDelYn(java.lang.Integer,java.lang.String,java.lang.String)! No property findbyBbsSeq found for type Bbs!

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: org.springframework.data.mapping.PropertyReferenceException: No property findbyBbsSeq found for type Bbs!

at org.springframework.data.mapping.PropertyPath.(PropertyPath.java:90)

at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:437)

at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:413)

at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:366)

at java.util.concurrent.ConcurrentMap.computeIfAbsent(Unknown Source)

at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:348)

at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:331)

at org.springframework.data.repository.query.parser.Part.(Part.java:81)

at org.springframework.data.repository.query.parser.PartTree$OrPart.lambda$new$0(PartTree.java:249)

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

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

at java.util.Spliterators$ArraySpliterator.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.query.parser.PartTree$OrPart.(PartTree.java:250)

at org.springframework.data.repository.query.parser.PartTree$Predicate.lambda$new$0(PartTree.java:383)

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

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

at java.util.Spliterators$ArraySpliterator.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.query.parser.PartTree$Predicate.(PartTree.java:384)

at org.springframework.data.repository.query.parser.PartTree.(PartTree.java:92)

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

... 57 common frames omitted

728x90
반응형
728x90
반응형

EntityClass 파일에서 @Column(name = "COLUMN_NAME")가 두개 이상 존재

 

org.springframework.beans.factory.BeanCreationException: 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 javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: packageName.core.model.entity.EntityClass column: COLUMN_NAME (should be mapped with insert="false" update="false")

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.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1153)

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

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: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: packageName.core.model.entity.EntityClass column: COLUMN_NAME (should be mapped with insert="false" update="false")

at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)

at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)

at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)

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

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

... 17 common frames omitted

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: packageName.core.model.entity.EntityClass column: COLUMN_NAME (should be mapped with insert="false" update="false")

at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:862)

at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:880)

at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:902)

at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:634)

at org.hibernate.mapping.RootClass.validate(RootClass.java:267)

at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:354)

at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:298)

at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:468)

at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259)

at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)

at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)

at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)

... 21 common frames omitted

728x90
반응형
728x90
반응형

jpa entity 사용시 테이블 명을 중복으로 사용하는 경우 에러가 발생된다.

아래 에러 셈플을 기준으로 @Entity(name = "CONTENT_COLOR")를 ContentColor, ContentLink

두 entity 에서 동시에 사용하고 있다는 뜻이다.

 

 

* 에러 전문

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

20210629 16:56:24.634 [main] ERROR o.s.b.SpringApplication - Application run failed

org.springframework.beans.factory.BeanCreationException: 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.DuplicateMappingException: The [com.PackageName.core.model.entity.ContentColor] and [com.PackageName.core.model.entity.ContentLink] entities share the same JPA entity name: [CONTENT_COLOR] which is not allowed!

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.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1153)

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

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 com.PackageName.BookKeepingApplication.main(BookKeepingApplication.java:12)

Caused by: org.hibernate.DuplicateMappingException: The [com.PackageName.core.model.entity.ContentColor] and [com.PackageName.core.model.entity.ContentLink] entities share the same JPA entity name: [CONTENT_COLOR] which is not allowed!

at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.addEntityBinding(InFlightMetadataCollectorImpl.java:314)

at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:826)

at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:248)

at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:239)

at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:282)

at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1224)

at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1255)

at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)

at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)

at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)

at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)

at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)

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

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

... 17 common frames omitted

####

 

 

 

 

 

728x90
반응형
728x90
반응형

@Scheduled로 jpa repository의 save 를 이용하는 경우에 발생되었습니다.

 

정확히 문제가 된 부분은 아래 부분인데, 해당 부분에서 세션의 정보를 가져와 작성자를 쓰려고 했던게 문제입니다.

스케줄에 의해 진행되므로 세션이 없죠.

at packageName.core.model.entity.base.BaseModel.preUpdate(BaseModel.java:87)

 

그래서에 해당되는 부분의 save를 사용하지 않고 nativeQuery를 작성하여 처리하도록 변경하였습니다.

(세션정보를 가져오지 않도록 함)

at packageName.core.schedule.service.ScheduleService.removeAttachFileInServer(ScheduleService.java:42)

 

* 참고정보

 

자바에러-no thread-bound request found are you referring to request attributes outside of an actual web

제목이 좀 길다. 내가 겪었던 오류이다. no thread-bound request found are you referring to request att...

blog.naver.com

 

* 에러 전문

20210621 18:40:23.854 [scheduling-1] ERROR o.s.s.s.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task

org.springframework.dao.InvalidDataAccessApiUsageException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:371)

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

at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:566)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)

at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)

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

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.$Proxy112.save(Unknown Source)

at packageName.core.schedule.service.ScheduleService.removeAttachFileInServer(ScheduleService.java:42)

at packageName.core.schedule.ScheduleCron.job_60min(ScheduleCron.java:63)

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 java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

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

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(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)

Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)

at packageName.core.common.utils.SessionUtil.getSession(SessionUtil.java:22)

at packageName.core.model.entity.base.BaseModel.preUpdate(BaseModel.java:87)

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.hibernate.jpa.event.internal.EntityCallback.performCallback(EntityCallback.java:32)

at org.hibernate.jpa.event.internal.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:95)

at org.hibernate.jpa.event.internal.CallbackRegistryImpl.preUpdate(CallbackRegistryImpl.java:69)

at org.hibernate.event.internal.DefaultFlushEntityEventListener.invokeInterceptor(DefaultFlushEntityEventListener.java:368)

at org.hibernate.event.internal.DefaultFlushEntityEventListener.handleInterception(DefaultFlushEntityEventListener.java:350)

at org.hibernate.event.internal.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:301)

at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:172)

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

at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:230)

at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:93)

at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)

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

at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362)

at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453)

at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212)

at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380)

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)

at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562)

... 29 common frames omitted

 

 

 

 

728x90
반응형
728x90
반응형

컨트롤러와 관계 없이 jpa의 entity @PrePersist, @PreUpdate에서 바로 세션 정보를 꺼내고 싶었다.

그러나 지식이 짧은 관계로 방법을 몰랐는데 찾아서 간단히 기록을 남긴다.

 

1. 로그인 세션 기록

1
2
3
4
5
6
7
8
9
10
11
@PostMapping(value = "/login")
public RestResponse<Member> loginProcess(@RequestBody LoginReqDTO reqDTO, HttpServletRequest request) throws Exception {
    // 로그인 계정의 정보 조회        
    Member memberinfo = serviceClass.checkLogin(reqDTO);
    
    if (memberinfo != null && memberinfo.getMemSeq() != null && memberinfo.getMemSeq() > 0) {
        // 세션에 로그인 계정정보 기록
        request.getSession().setAttribute("memberinfo", memberinfo);
    }    
    return new RestResponse<>(memberinfo);
}
cs

8번 라인의 "memberinfo"으로 세션에 로그인 계정정보 기록!

 

2. 세션 정보를 얻기 위한 유틸

1
2
3
4
5
6
public class SessionUtil {
    public static HttpSession getSession() {
        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        return attr.getRequest().getSession();
    }
}
cs

3. entity의 @PrePersist, @PreUpdate에서 세션에 기록된 접속자의 정보 습득

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
@PrePersist
public void prePersist() {
    this.crtDt = new Date();
    this.updDt = this.crtDt;
 
    // created/updated by 업데이트
    Member user = (Member) SessionUtil.getSession().getAttribute("memberinfo");
    if (user != null) {
        this.crtBy = user.getMemSeq();
        this.updBy = this.crtBy;
    } else {
        this.crtBy = 0;
        this.updBy = 0;
    }
 
}
 
@PreUpdate
public void preUpdate() {
    this.updDt = new Date();
        
    // updated by 업데이트
    Member user = (Member) SessionUtil.getSession().getAttribute("memberinfo");
    if (user != null) {
        this.updBy = user.getMemSeq();
    } else {
        this.updBy = 0;
    }
       
}
cs

7, 23번 라인에서 1번 코드에서 작성한 "memberinfo"를 이용해서 정보 로그인 계정 정보를 얻기

 

 

해당 방법을 이용하면 원하는 어떤 곳에서도 세션 정보를 얻을 수 있다.

 

 

 

 

728x90
반응형

+ Recent posts