Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring boot - calculated field

So, I have an entity, that has field start_date (java.util.Date is the type).

I want to have another field, that would automatically populate with integer that corresponds to day of week (as a number 1 for sunday, 2 for monday, etc.) of starting date.

Here's fragment of my entity:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

@DateTimeFormat(pattern = "yyyy-MM-dd")
@Temporal(TemporalType.DATE)
private Date start_date;

I've tried to add the calculated field in the following way:

@Column(name = "weekday")
@Formula("(select dayofweek(l.start_date) from Lesson l where l.id = id)")
private Integer weekDay;

However, when looking at the Lesson table in H2 console, there's no such column as "weekday"

I also tried other option - without @Formula annotation and with a setter that takes start_date parameter, but I guess this setter is never called, since the column "weekday" is populated with null. Here's the setter I've tried to use as an alternative solution:

    public void setWeekDay(Date start_date) {
    Calendar c = Calendar.getInstance();
    c.setTime(start_date);
    this.weekDay = c.get(Calendar.DAY_OF_WEEK);
}

It's obvious that I'm missing something here, it's probably because I'm still learning Spring boot...

To sum up - I want to have a column in table Lesson, that is calculated from another column of the same table.

like image 401
mr_kite Avatar asked Oct 17 '22 08:10

mr_kite


1 Answers

@Formula means your field to be calculated by your rules. This entity field is not column in db. This field is calculating for each entity in loading time by specified rule.

If annotation @Column(name = "weekday") would work near @Formula you would be really confused if you expect in loaded entity same value as in DB but here is calculated one and different (inconsistent situation).

If you want save here value from the Lesson table you should remove @Formula and use @EntityListeners({YourEntityJpaCallbacksListener.class}) In spring bean YourEntityJpaCallbacksListener you can define methods marked with @PreUpdate or @PrePersist and use correspond operations to set calculated value into weekday.

for example:

@EntityListeners({YourEntityJpaCallbacksListener.class})
@Entity
public class YourEntity{
    // your code
}

@Component
public class YourEntityJpaCallbacksListener {
    @Autowired
    private LessonRepository lessonRepository;

    @PreUpdate
    void preUpdate(YourEntity yourEntity) {
        if (recurrentRuleRepository.exists(yourEntity.getId())) {
            Integer weekDay = lessonRepository.findOne(yourEntity.getId());
            yourEntity.setWeekDay(weekDay);
        }
    }

}
like image 162
Sergii Avatar answered Nov 03 '22 23:11

Sergii