Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.emobile</groupId>
<artifactId>SpringToDo</artifactId>
<artifactId>SpringToDo-hib</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringToDo</name>
<description>SpringToDo</description>
Expand Down Expand Up @@ -40,11 +40,20 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.6.1.Final</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.zaxxer</groupId>-->
<!-- <artifactId>HikariCP</artifactId>-->
<!-- <version>5.0.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-jdbc</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.emobile.springtodo.aop;
package com.emobile.springtodo.aop.logger;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.emobile.springtodo.aop;
package com.emobile.springtodo.aop.logger;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/com/emobile/springtodo/aop/session/LazySession.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.emobile.springtodo.aop.session;

import com.emobile.springtodo.model.util.SessionAction;
import com.emobile.springtodo.model.util.TransactionalType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LazySession {
TransactionalType type() default TransactionalType.IGNORE;

SessionAction action() default SessionAction.CLOSE;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.emobile.springtodo.aop.session;

import com.emobile.springtodo.model.util.SessionAction;
import com.emobile.springtodo.model.util.TransactionalType;
import com.emobile.springtodo.util.SessionUtil;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.hibernate.Transaction;
import org.hibernate.resource.transaction.spi.TransactionStatus;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@Aspect
@Component
public class LazySessionAdvice {
private final SessionUtil sessionUtil;

@Before(value = "@annotation(param)")
public void beforeLazySession(LazySession param) {
if (param.type() == TransactionalType.AROUND) {
sessionUtil.getSession().beginTransaction();
}
}

@AfterThrowing(value = "@annotation(LazySession)")
public void afterThrowingLazySession(JoinPoint joinPoint) {
Transaction transaction = sessionUtil.getSession().getTransaction();
if (transaction != null) {
transaction.rollback();
}
sessionUtil.closeSession();
}

@AfterReturning(value = "@annotation(param)")
public void afterReturnLazySession(LazySession param) {
if (param.type() == TransactionalType.AROUND) {
sessionUtil.getSession().getTransaction().commit();
}
if (param.action() == SessionAction.CLOSE){
sessionUtil.closeSession();
}
if (param.action() == SessionAction.CHECK){
boolean oneOf = sessionUtil.getSession()
.getTransaction()
.getStatus()
.isOneOf(TransactionStatus.NOT_ACTIVE);
if (oneOf){
sessionUtil.closeSession();
}
}
}
}
37 changes: 0 additions & 37 deletions src/main/java/com/emobile/springtodo/config/AppConfig.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
package com.emobile.springtodo.config;

import com.emobile.springtodo.config.property.cache.AppCacheProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import javax.sql.DataSource;
import java.time.Clock;

/**
Expand All @@ -27,37 +21,6 @@
@EnableConfigurationProperties(AppCacheProperties.class)
@PropertySource("classpath:config/application.yml")
public class AppConfig {
@Value("${spring.datasource.driver-class-name}")
private String dataSourceDriverClassName;
@Value("${spring.datasource.url}")
private String dataSourceUrl;
@Value("${spring.datasource.username}")
private String dataSourceUsername;
@Value("${spring.datasource.password}")
private String dataSourcePassword;

@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();

dataSource.setDriverClassName(dataSourceDriverClassName);
dataSource.setUrl(dataSourceUrl);
dataSource.setUsername(dataSourceUsername);
dataSource.setPassword(dataSourcePassword);

return dataSource;
}

@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}

@Bean
public PlatformTransactionManager txManager() {
return new DataSourceTransactionManager(dataSource());
}

@Bean
public Clock clock() {
return Clock.systemDefaultZone();
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/com/emobile/springtodo/config/HibernateConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.emobile.springtodo.config;

import com.emobile.springtodo.model.entity.Task;
import com.emobile.springtodo.model.entity.User;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HibernateConfig {
@Value("${spring.datasource.driver-class-name}")
private String dataSourceDriverClassName;
@Value("${spring.datasource.url}")
private String dataSourceUrl;
@Value("${spring.datasource.username}")
private String dataSourceUsername;
@Value("${spring.datasource.password}")
private String dataSourcePassword;

@Bean
public SessionFactory sessionFactory() {
return new org.hibernate.cfg.Configuration()
.setProperty("hibernate.connection.driver_class", dataSourceDriverClassName)
.setProperty("hibernate.connection.url", dataSourceUrl)
.setProperty("hibernate.connection.username", dataSourceUsername)
.setProperty("hibernate.connection.password", dataSourcePassword)
.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect")
.setProperty("hibernate.show_sql", "true")
.addAnnotatedClass(User.class)
.addAnnotatedClass(Task.class)
.buildSessionFactory();
}



// @Bean
// public PlatformTransactionManager transactionManager() {
// JpaTransactionManager transactionManager = new JpaTransactionManager();
// transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
// return transactionManager;
// }

// @Bean
// public HibernateTransactionManager transactionManager() {
// HibernateTransactionManager txManager = new HibernateTransactionManager();
// txManager.setSessionFactory(sessionFactory().getObject());
// return txManager;
// }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.emobile.springtodo.controller;

import com.emobile.springtodo.aop.LazyLogger;
import com.emobile.springtodo.aop.logger.LazyLogger;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.emobile.springtodo.controller;

import com.emobile.springtodo.aop.LazyLogger;
import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.mapper.UserMapper;
import com.emobile.springtodo.model.dto.user.UserSaveRequest;
import com.emobile.springtodo.model.dto.util.SimpleResponse;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.emobile.springtodo.controller;

import com.emobile.springtodo.aop.LazyLogger;
import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.mapper.TaskMapper;
import com.emobile.springtodo.model.dto.task.TaskInsertRequest;
import com.emobile.springtodo.model.dto.task.TaskListResponse;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.emobile.springtodo.controller;

import com.emobile.springtodo.aop.LazyLogger;
import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.mapper.UserMapper;
import com.emobile.springtodo.model.dto.user.UserInsertRequest;
import com.emobile.springtodo.model.dto.user.UserListResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.emobile.springtodo.exception.DeleteEntityWithReferenceException;
import com.emobile.springtodo.exception.EntityNotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.TransactionException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -78,6 +79,22 @@ public ResponseEntity<ErrorResponseBody> badRequest(
return buildResponse(HttpStatus.BAD_REQUEST, ex, webRequest);
}

/**
* ExceptionHandler for {@link TransactionException}.
*
* @param ex exception type of {@link TransactionException}.
* @param webRequest web request for exception description.
* @return {@link ResponseEntity} with {@link ErrorResponseBody}.
* @see #buildResponse(HttpStatus, Exception, WebRequest)
*/
@ExceptionHandler(TransactionException.class)
public ResponseEntity<ErrorResponseBody> badRequest(
TransactionException ex,
WebRequest webRequest
) {
return buildResponse(HttpStatus.BAD_REQUEST, ex, webRequest);
}

/**
* ExceptionHandler for {@link EntityNotFoundException}.
*
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/emobile/springtodo/mapper/TaskMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.emobile.springtodo.model.dto.task.TaskSaveRequest;
import com.emobile.springtodo.model.entity.Task;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.ReportingPolicy;

Expand Down Expand Up @@ -45,8 +46,7 @@ public interface TaskMapper {
* @param model {@link Task} for mapping.
* @return mapped {@link TaskResponse}.
*/
// @Mapping(target = "createdAt", qualifiedByName = "OffsetDateTimeToString")
// @Mapping(target = "updatedAt", qualifiedByName = "OffsetDateTimeToString")
@Mapping(source = "author.id", target = "authorId")
TaskResponse modelToResponse(Task model);


Expand Down
33 changes: 31 additions & 2 deletions src/main/java/com/emobile/springtodo/model/entity/Task.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
package com.emobile.springtodo.model.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
Expand All @@ -22,35 +32,54 @@
@Getter
@FieldNameConstants
@Builder
@Entity
@Table(name = "tasks")
public class Task implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* Long Task id.
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = Fields.id)
private Long id;
/**
* Task name.
*/
@Column(name = Fields.name)
private String name;
/**
* Task description.
*/
@Column(name = Fields.description)
private String description;
/**
* Task {@link TaskStatus} status.
*/
@Enumerated(EnumType.STRING)
@Column(name = Fields.status)
private TaskStatus status;
/**
* Task creation time without timezone.
*/
@Column(name = "created_at")
private LocalDateTime createdAt;
/**
* Task update time without timezone.
*/
@Column(name = "updated_at")
private LocalDateTime updatedAt;
/**
* The User id who owns the Task.
* The User who owns the Task.
*/
private Long authorId;
@EqualsAndHashCode.Exclude
@ManyToOne
@JoinColumn(name = "author_id", referencedColumnName = "id")
private User author;

@EqualsAndHashCode.Include
public Long getAuthorId() {
return author.getId();
}
}
Loading