Тип «День рождения» не определяет дату рождения (День рождения), которая здесь применима

BirthDateConverter:

package package1;
import java.sql.Date;
import package1.Birthday;
import jakarta.persistence.*;
import java.util.Optional;

public class BirthDayConverter implements AttributeConverter<Birthday, Date>{

    @Override
    public Date convertToDatabaseColumn(Birthday attribute) {
        return Optional.ofNullable(attribute)
                .map(Birthday::birthDate)
                .map(Date::valueof)
                .orElse(null);
    }

    @Override
    public Birthday convertToEntityAttribute(Date dbData) {
        return null;
    }
}

мой HibernateRunner:

import java.time.LocalDate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.*;

public class HibernateRunner{
    public static void main(String[] args) {
        Configuration configuration = new Configuration();
//      configuration.setPhysicalNamingStrategy(new CamelCaseToUnderscoresNamingStrategy());
        configuration.addAnnotatedClass(User.class);
        configuration.configure();
        
        try ( SessionFactory sessionFactory = configuration.buildSessionFactory();
            Session session = sessionFactory.openSession()){
            session.beginTransaction();
            User user = User.builder()
                    .username("[email protected]")
                    .firstname("stro4ni4ek")
                    .lastname("Magomedov")
                    .birthDate(LocalDate.of(2010, 11, 20))
                    .age(13)
                    .role(Role.ADMIN)
                    .build();
            session.save(user);
            session.getTransaction().commit();
        }
    }
}

User:

import java.time.LocalDate;
import jakarta.persistence.*;
import lombok.*;
import package1.Birthday;
    
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "users", schema = "public")
    
public class User {
        
    @Id
    private String username;
    private String firstname;
    private String lastname;
    @Column(name = "birth_date")
    private Birthday birthDate;
    @Enumerated(EnumType.STRING)
    private Role role;
    
}

Ошибка:

Description Resource    Path    Location    Type
The type Birthday does not define birthDate(Birthday) that is applicable here   BirthDayConverter.java  /CrunchifySpringMVCFramework/src/main/java/package1 line 12 Java Problem`

Birthday:

package package1;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public record Birthday(LocalDate BirthDate) {
    
    public long getAge() {
        return ChronoUnit.YEARS.between(BirthDate, LocalDate.now());
    }
    
}

Role:

public enum Role {
    USER, ADMIN
}

Ответы (1 шт):

Автор решения: Nowhere Man

Проблема в том, что класс кортежа Birthday содержит свойство, написанное с большой буквы:

public record Birthday(LocalDate BirthDate) { 
    // ... 
}

Соответственно в классе конвертере компилятор не может найти геттер, на который ссылается строка кода .map(Birthday::birthDate).

Для исправления данной ошибки достаточно переименовать свойство кортежа, чтобы оно соответствовало стандартному соглашению Java:

public record Birthday(LocalDate birthDate) { 
    public long getAge() {
        return ChronoUnit.YEARS.between(birthDate, LocalDate.now()); // аналогично здесь
    }
}

Альтернативное "решение": использовать корректную ссылку на метод Birthday::BirthDate, но в таком случае нарушается соглашение об именовании.

Аналогично, есть опечатка в ссылке на метод .map(Date::valueof) -- должно быть .map(Date::valueOf).


В любом случае также следует корректно реализовать метод конвертера convertToEntityAttribute

@Override
public Birthday convertToEntityAttribute(Date dbData) {
    return new Birthday(dbData.toLocalDate());
}        
→ Ссылка