어느순간 SpringFramework을 사용하는 프로젝트는 springboot가 대세가 되버렸고, 

이제는 점점 springboot + maven + mybatis 에서 maven자리를 gradle이 대체하는 추세인듯하다. (개인적인 느낌)

여전히 Maven이 친숙한 입장에서 gradle이 익숙하지 않은데서 오는 삽질이 또다시 반복되고 있다.(ㅠ.ㅠ)

(앞으로도 개발을 놓기전까지 이런 패턴은 계속될듯...)

 

eclipse나 sts등의 IDE에서 gradle로 관리하는 프로젝트에서 mybatis mapper.xml 에서 domain class의 typealias를 인식하지 못하고 오류표시를 내곤한다.

Class/TypeAlias 인식하지 못한 오류

그런데 springboot로 실행하면 특별한 오류없이 잘 실행되곤 한다. 그냥 내버려두고 싶다가도 계속 눈에 거슬리다보니 원인과 해결책을 찾아 메모해둔다. 

 

개인의견으로는 Spring의 설정이 xml 에서 annotation으로 변화되면서 실행시점에 mapper와 domain class를 인식하기에 실행에는 문제가 없으나 IDE Tool에서는 이를 인지하기엔 추가적인 설정이 필요하지만 적용하지 않아 발생하는 오류로 보인다.

기본적인 springboot+mybatis+gradle  프로젝트 설정 이후 DataSource관련 추가설정을 별도의 class로 분리하여 아래와 같이 설정했다.

 

1. 일반적인 springboot 설정

@SpringBootApplication
public class TestBootApplication {

	public static void main(String[] args) {
		
		SpringApplication app = new SpringApplication(TestBootApplication.class);
		app.run(args); 
	}

2. DataSource Config설정

@Configuration
@ComponentScan
@EnableTransactionManagement
public class DataSourceConfig {
	
	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
		SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(dataSource);
		sessionFactory.setVfs(SpringBootVFS.class); 
		
		Properties properties = new Properties();
		properties.setProperty("callSettersOnNulls", "true");
		sessionFactory.setConfigurationProperties(properties);
		
		org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
		configuration.setCallSettersOnNulls(true);
		sessionFactory.setConfiguration(configuration);
		sessionFactory.setTypeAliasesPackage("com.test.dto");

		return sessionFactory.getObject();
	}	
}

여기까지만 해도 실행에는 문제가 발생하지 않는다. 하지만 서두의 문제처럼 IDE에서 오류가 발생한다.

 

application.properties나 application.yml에 아래의 설정을 추가해주자.

mybatis:
  type-aliases-package: com.test.dto
  mapper-locations: com/test/mapper/*.xml

추가로

위의 mapper-locations 는 일정한 규칙대로 일괄적용하는 방식이라면

config-location=mybatis-config.xml 형식으로 지정하면 선택적인 mapper및 alias name을 적용할 있다. 

아래는 mybatis-config.xml 파일의 샘플이다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
 	<settings>
		<setting name="callSettersOnNulls"    value="true"/>
		<setting name="jdbcTypeForNull"       value="NULL" />
		<setting name="cacheEnabled"          value="false" />
		<setting name="useGeneratedKeys"      value="true" />
		<setting name="defaultExecutorType"   value="REUSE" />
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
 
  <mappers> 
    <mapper resource="com/test/oracle/mapper/TestMapper.xml"/>
    <mapper resource="com/test/oracle2/mapper/UserDao.xml"/>
    ...
  </mappers>

  <typeAliases>
	<typeAlias type="com.test.dto.UserDto" alias="User" />
  </typeAliases>

 

 



eclipse나 sts에서 Gradle프로젝트를 import하거나 할때 Project and External Dependencies가 나오지 않는 경우가 종종 발생한다.

이전 Maven프로젝트에서 의존성라이브러인 Maven Dependencies가 나오지 않는 경우와 유사한것이다.

구글링을 통해 이런저런 방법을 사용해 보았으나 딱히 적용이 안되어서 본인의 경우에는 프로젝트 루트에 위치한 .project 파일을 직접 수정해서 살려냈다. 

 

위 파일은 Ctrl + Shift + r 을 눌러 파일명으로 검색해서 찾는것이 빠르다. 숨겨진 파일이고 Project Explorer에 나오지 않음.

아래는 일반적인 gradle project의 .project 파일형태이다.

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>testGradle</name>
	<comment>test</comment>
	<projects></projects>
	<buildSpec>
		<buildCommand>
			<name>org.eclipse.jdt.core.javabuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.wst.validation.validationbuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
	</buildSpec>
	<natures>
		<nature>org.eclipse.jdt.core.javanature</nature>
		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
		<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
		<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
		<nature>net.harawata.mybatipse.MyBatisNature</nature>
	</natures>
</projectDescription>

아래는 Project and External Dependencies 가 나오지 않을때의 .project파일이다.

 

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>testGradle</name>
	<comment>test</comment>
	<projects></projects>
	<buildSpec>
		<buildCommand>
			<name>org.eclipse.jdt.core.javabuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.wst.common.project.facet.core.builder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.wst.validation.validationbuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
	</buildSpec>
	<natures>
		<nature>org.eclipse.jdt.core.javanature</nature>
		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
		<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
		<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
		<nature>net.harawata.mybatipse.MyBatisNature</nature>
	</natures>
</projectDescription>

 

예상하기론 Project Properties의 Buidlers에 나오는 목록을 나타내는 파일인데 여기서 Gradle과 상관없는 project.facet.core.nature형태가 추가가 되는 경우이다. 

 

위 Builders에서 Facet Project Validation Builder를 Remove하고 싶은데 버튼이 비활성화가 되어 제거할수 없다. checkbox해제를 해도 해결되지 않는다. 

그래서 결론은 .project파일을 직접 수정해서 이 프로젝트가 Gradle 프로젝트라는 것을 eclipse에게 알려줘야 하는것으로 판단된다. 

결론은 .proejct파일을 열어서 facet 부분을 제거하고 새로고침하면  Project and External Dependencies 항목이 정상적으로 나온다는 사실.