Создание веб-приложения (*.war) - Детализация логов при работе с внешним веб-сервером Weblogic, c Spring boot 2.x, logback, Hibernate
Я использую oracle 11.x, Spring boot 2.x , maven, weblogic – в качестве внешнего сервера.
- точка входа
@SpringBootConfiguration
@SpringBootApplication
public class WebSpringBootJarApplication
extends SpringBootServletInitializer
implements WebApplicationInitializer {
private static final Logger LOGGER = LoggerFactory.getLogger( WebSpringBootJarApplication.class );
public static void main(String[] args) {
SpringApplication.run(WebSpringBootJarApplication.class, args);
LOGGER.info("Start an application...");
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
LOGGER.info("There is building the web application!");
return builder.sources(WebSpringBootJarApplication.class);
}
}
- Сущность
@MappedSuperclass
public abstract class DifferentTypesEntityTwo {
@Id
@SequenceGenerator(name = "jpaSequence.DifferentTypes",
sequenceName = "SEQUENCE_DIFF_TYPES",
allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "jpaSequence.DifferentTypes")
private Long id;
@Size(message = "name{ weblogic.war.spring.boot.dao.domain.differenttypes.DifferentTypesEntityTwo.size}", max = 5)
private String name;
public DifferentTypesEntityTwo() {
}
@PrePersist
private void init(){
this.name = "Lamborghini";
}
…
}
- продолжение сущности
@Entity
@Table(name = "DIFFERENT_TYPES")
public class DifferentTypesEntityEightProduce extends DifferentTypesEntitySix {
@Enumerated(EnumType.STRING)
private Status status;
public DifferentTypesEntityEightProduce() {
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
…
}
- репозиторий
public interface DifferentTypesSaveRepository extends CrudRepository<DifferentTypesEntityEightProduce, Long> {
}
- Service
public interface DifferentTypesSaveService {
DifferentTypesDtoEightProduce writeData(DifferentTypesDtoEightProduce dto);
Iterable<DifferentTypesDtoEightProduce> setListData(Iterable<DifferentTypesDtoEightProduce> dtoList);
}
@Service
public class DifferentTypesSaveServiceImpl implements DifferentTypesSaveService {
private DifferentTypesSaveRepository differentTypesSaveRepository;
private DifferentTypesMapper differentTypesMapper;
@Autowired
public DifferentTypesSaveServiceImpl(DifferentTypesSaveRepository differentTypesSaveRepository,
DifferentTypesMapper differentTypesMapper) {
this.differentTypesSaveRepository = differentTypesSaveRepository;
this.differentTypesMapper = differentTypesMapper;
}
@Transactional
@Override
public DifferentTypesDtoEightProduce writeData(DifferentTypesDtoEightProduce dto) {
DifferentTypesEntityEightProduce entity = transform(dto);
DifferentTypesEntityEightProduce save = this.differentTypesSaveRepository.save(entity);
return transformToDto(save);
}
@Transactional
@Override
public Iterable<DifferentTypesDtoEightProduce> setListData(Iterable<DifferentTypesDtoEightProduce> dtoList) {
Iterable<DifferentTypesEntityEightProduce> entityList = transformDtoToListEntity(dtoList);
Iterable<DifferentTypesEntityEightProduce> entityListSaved = this.differentTypesSaveRepository.saveAll(entityList);
return transformEntityListToDto(entityListSaved);
}
private Iterable<DifferentTypesDtoEightProduce> transformEntityListToDto(Iterable<DifferentTypesEntityEightProduce> entityList){
return this.differentTypesMapper.differentTypesListEntityToDifferentTypesDto(entityList);
}
private Iterable<DifferentTypesEntityEightProduce> transformDtoToListEntity(Iterable<DifferentTypesDtoEightProduce> dtoList){
return this.differentTypesMapper.differentTypesListDtoToDifferentTypesEntity(dtoList);
}
private DifferentTypesDtoEightProduce transformToDto(DifferentTypesEntityEightProduce entity){
return this.differentTypesMapper.differentTypesEntityToDifferentTypesDto(entity);
}
private DifferentTypesEntityEightProduce transform(DifferentTypesDtoEightProduce dto){
return this.differentTypesMapper.differentTypesDtoToDifferentTypesEntity(dto);
}
}
- application.properties
spring.main.banner-mode=off
####################################################
# Oracle 11x
####################################################
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.datasource.url=jdbc:oracle:thin:@//SRV-ORACLE01:1521/ora_fiz
spring.datasource.username=MARK
spring.datasource.password=pass
#spring.datasource.driver-class-oracle.jdbc.driver.OracleDriver
#-----------------------------------------------------------------------#
#**** При выводе приложения в production, отключите данные опции.*******#
#-----------------------------------------------------------------------#
#** Логгирование Sql-запросов ******************************************#
#-----------------------------------------------------------------------#
#Создание базы данных и таблиц, на основе указанных сущностей
spring.jpa.hibernate.ddl-auto=update
#Показывает только запросы ( вместо параметров, будут вопросительные знаки)
logging.level.org.hibernate.SQL=DEBUG
#показываеть sql-запросы в отформатированном виде
spring.jpa.properties.hibernate.format_sql=true
#данный параметр выводит в консоль результат запроса сформированного PreparedStatements
logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE
#Выполнение привязки значений к параметрам JDBC инструкции, в случае использования PreparedStatements
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
#Отключение режима Open Session In View (OSIV), который включен по умолчанию
spring.jpa.open-in-view=false
#управление отключением запуска очистки архивных лог-файлов
logging.file.clean-history-on-start=false
spring.profiles.active=production
logging.config=classpath:logger/logback-spring.xml
logging.file.dir=logs
logging.file.name.var=log.log
# В данном случае, архивный каталог создается каждую 'минуту'.
# Здесь обрататите внимание на `dd-` в имени архивного файла. Это означает, что архивный
# файл будет создаваться каждый день;
logging.file.archive.format.name=program_.%d{dd-MM-yyyy}.log
- logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="10 seconds" >
<!-- Переопределим стандартные настройки системы логгирования.-->
<include resource="logger/settingslogger/defaults-spring.xml"/>
<!--Профиль по умолчанию, вывод сообщений только в консоль.-->
<springProfile name="default">
<include resource="logger/consolelogger/console-appender-spring.xml"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<!--Профиль по умолчанию, вывод сообщений только в консоль.-->
<springProfile name="production">
<!-- настройки аппендеров для текущего профиля-->
<include resource="logger/productionappenderlogger/logback-appender-production-spring.xml"/>
<!-- Указываем для пакета, какой уровень логгирования, будет обрабатываться
текущим профилем.-->
<logger name="org.springframework.web" level="DEBUG">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="org.springframework.data" level="DEBUG">
<appender-ref ref="CONSOLE"/>
</logger>
<!-- Указываем для пакета, какой уровень логгирования, будет обрабатываться
текущим профилем.-->
<logger name="weblogic.war.spring.boot" level="ERROR">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="weblogic.war.spring.boot" level="INFO">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="weblogic.war.spring.boot" level="INFO">
<appender-ref ref="FILE-ROLLING"/>
</logger>
<!-- Указываем для пакета, какой уровень логгирования, будет обрабатываться
текущим профилем.-->
<logger name="weblogic.war.spring.boot" level="INFO">
<appender-ref ref="FILE-ROLLING"/>
</logger>
</springProfile>
</configuration>
Когда postman отправляет запрос, то в ответ получаю
{ "timestamp": "2020-03-05T13:47:37.128+0000", "status": 500, "error": "Internal Server Error", "message": "JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is weblogic.transaction.RollbackException: setRollbackOnly called on transaction", "path": "/sat/api/save/differentTypes" }
В консоль вот это:
05-03-2020 16:47:37.095 DEBUG 10500 [ (self-tuning)'] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to [weblogic.war.spring.boot.service.dto.differenttypes.DifferentTypesDtoEightProduce@f8bde55f Different (truncated)...] 05-03-2020 16:47:37.124 DEBUG 10500 [ (self-tuning)'] o.s.web.servlet.DispatcherServlet : Failed to complete request: org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is weblogic.transaction.RollbackException: setRollbackOnly called on transaction
Как можно в данном случае настроить подробный вывод логов ошибок, которые появляются когда Hibernate выбрасывает исключения при работе с базой данных…
А также, когда в PreparedStatement уже вставляются значения, которые должны быть записаны в базу ...
Но при этом, в качестве логгера (основного) должна выступать настройка Logback