spring-bootでspring-data-jpaを使う場合JTAはHIkariCPが特に何も設定しなくても使われる。通常はこれで何ら問題は無いが以下ではJTAをAtomikosに変更するやり方のメモ。
pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> </parent> <properties> <java.version>10.0</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </dependency> </dependencies>
現時点(2018/08/21)最新版の2.0.4.RELEASEだとspring-data-jpaが動作しなかったので2.0.3にしている。
javax.xml.bind
については ClassNotFoundException for javax.xml.bind.JAXBException with Spring Boot when swich to Java 9 - Stack Overflow を参照。
JTAをAtomikosに変更する場合は依存性にspring-boot-starter-jta-atomikos
を追加するだけで良い。
プロパティ
application.properties
で以下のように設定する。例えば、以下によりcom.atomikos.icatch.max_timeout
を変更できる。
spring.jta.atomikos.properties.max_timeout=312345
プロパティ一覧についてはAtomikosProperties (Spring Boot Docs 2.0.4.RELEASE API) を参照。
ソースコード
動作確認用のソースコード。HelloWorldレベルのことしかやってない。テーブルについては作ってあるもんとする。
package kagamihoge.springdatajpa; import java.util.Optional; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Hello world! * */ @SpringBootApplication public class App implements CommandLineRunner{ public static void main(String[] args) { SpringApplication.run(App.class, args).close(); } @Autowired UserRepository userRepository; @Transactional @Override public void run(String... args) throws Exception { Optional<User> user = userRepository.findById(1L); System.out.println(user.get().getEmail()); } }
package kagamihoge.springdatajpa; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "users") public class User { @Id private Long userId; private String username; private String password; private String email; public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
package kagamihoge.springdatajpa; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends CrudRepository<User, Long> { }
spring.datasource.url=jdbc:postgresql://192.168.10.23:5432/testdb spring.datasource.username=postgres spring.datasource.password=xxxx