Hibernate родной тип запроса SQL сопоставления от java.sql.Date к java.time.LocalDate - PullRequest
0 голосов
/ 06 ноября 2018

Я делаю запрос SELECT, используя собственный запрос Hibernate, как показано ниже:

public List<SomeDTO> findDTOs() {
    StringBuilder sql = new StringBuilder();
    sql.append(" SELECT id as id, localDateColumn as date, ");

    sql.append(" FROM t");
    Query query = entityManager.createNativeQuery(sql.toString());
    query.unwrap(SQLQuery.class)
        .addScalar("id", StandardBasicTypes.LONG)
        .addScalar("localDateColumn", DateType.INSTANCE)
        .setResultTransformer(Transformers.aliasToBean(SomeDTO.class));
    return query.getResultList();
  }

Я пытался использовать StandardBasicTypes.DATE или DateType.INSTANCE, который не работает. Я знаю, что это нормально работает для отображения java.sql.Types#DATE и java.util.Date.

Я хотел бы знать, как мне сопоставить java.sql.Types#DATE с java.time.LocalDate.

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

Поскольку я не использую Entity для типа возвращаемых данных. AttributeConverter в этом случае бесполезен. Я решил это путем ручного преобразования java.util.Date в java.time.LocalDate в установщике поля.

Сеттер будет выглядеть так:

public void setLocalDateColumn(java.util.Date value){
    // convert into LocalDate
    // set
}

Если вы получаете UnsupportedOperationException во время конвертации. Вы все еще можете получить java.sql.Date здесь, завернутый в java.util.Date. Сделай это как: Instant.ofEpochMilli(value.getTime()).atZone(DefaultZoneId).toLocalDate();

0 голосов
/ 12 ноября 2018

Есть много вещей, которые не подходят к вашему подходу.

Рискованные SQL-инъекции

То, как вы строите SQL с использованием конкатенации строк, очень рискованно и может подвергнуть ваше приложение воздействию SQL-инъекций .

StringBuilder sql = new StringBuilder();
sql.append(" SELECT id as id, localDateColumn as date, ");

sql.append(" FROM t");
Query query = entityManager.createNativeQuery(sql.toString());

Более того, это даже неправильно, поскольку вы добавляете , перед предложением FROM. Вам нужно использовать Criteria API , если вы хотите динамически создавать запросы.

Псевдонимы используются неправильно

Вы задаете для столбца localDateColumn псевдоним date следующим образом:

sql.append(" SELECT id as id, localDateColumn as date, ");

Но затем вы используете localDateColumn при настройке Типа гибернации с помощью addScalar:

.addScalar("localDateColumn", DateType.INSTANCE)

Теперь, согласно заголовку вашего вопроса, если localDateColumn - это тип столбца MySQL DATE, и вы хотите сопоставить его с LocalDate Java-объектом, вы должны сделать это так:

.addScalar("date", LocalDateType.INSTANCE)
0 голосов
/ 06 ноября 2018

Вы можете использовать AttributeConverter для отображения java.sql.Date в java.time.LocalDate.

import java.sql.Date;
import java.time.LocalDate;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {

    @Override
    public Date convertToDatabaseColumn(LocalDate localDate) {
        return (localDate == null ? null : Date.valueOf(localDate));
    }

    @Override
    public LocalDate convertToEntityAttribute(Date sqlDate) {
        return (sqlDate == null ? null : sqlDate.toLocalDate());
    }
}

Детали: https://www.baeldung.com/jpa-attribute-converters

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...