Kirill
Kirill

Reputation: 6036

Why @Column might not work for methods?

I have a Spring Boot application with JPA and Hibernate Maven dependencies. Database is PosgreSQL.

I would like to create fields in a database based on methods.

So I have an entity class:

@Entity
@Table(name="test_my_entity")
public class MyEntity {

    @Id
    @GeneratedValue
    private Long id;

    protected String name;

    @Transient
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar myXMLDate;

    protected Calendar myDateProperty;

    @Column(name = "my_date")
    private Calendar isCalendar() {
        return new GregorianCalendar(myXMLDate.getYear(), myXMLDate.getMonth(), myXMLDate.getDay());
    }

    @Column(name = "my_str")
    public String myStr() {
        return "My string";
    }


    public MyEntity() {
    }
}

However I receive the following structure:

enter image description here

All annotations on methods are ignored.

Could anyone please give me some advice why it might happen and how to create needed fields properly?

Upvotes: 1

Views: 529

Answers (2)

Kirill
Kirill

Reputation: 6036

So I have found the solution. So that you can receive values from methods you should add @Access annotations and also make @Transient variables.

So Hibernate will create neccesary fields and during commit will use values from methods to fulfill them.

Also here is an example of how to convert XMLGregorianCalendar to Calendar - the format that Hibernate can use successfully.

Here is a working example:

@Entity
@Access(AccessType.FIELD)
@Table(name="test_my_entity")
public class MyEntity {

    @Id
    @GeneratedValue
    private Long id;

    @XmlAttribute(name = "name")
    @Transient
    protected String name;

    @XmlSchemaType(name = "dateTime")
    @Transient
    protected XMLGregorianCalendar myXMLDate;

    @Transient
    private Calendar calendarDate;

    @Access(AccessType.PROPERTY)
    @Column(name = "calendar_date")
    private Calendar getCalendarDate() {
        return new GregorianCalendar(myXMLDate.getYear(), myXMLDate.getMonth(), myXMLDate.getDay());
    }

    @Access(AccessType.PROPERTY)
    @Column(name = "my_str_name")
    public String getName() {
        return "My string";
    }

    //...setters here

    public MyEntity() {
    }
}

Upvotes: 0

Adeel Ansari
Adeel Ansari

Reputation: 39907

The methods must follow, Java Bean convention; precisely, public Getters and Setters. Moveover, properties must exist. Try this,

@Entity
@Table(name="test_my_entity")
public class MyEntity {

    private Long id;
    protected String name;
    private Calendar myDate;
    private String myStr;

    @Transient
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar myXMLDate;

    @Id
    @GeneratedValue
    public Long getId() {
      return id;
    }

    @Column(name = "my_date")
    public Calendar getMyDate() {
      return myDate;
    }

    @Column(name = "my_str")
    public String getMyStr() {
      return myStr;
    }

    // I don't get its purpose; hence not touching it.
    private Calendar isCalendar() {
        return new GregorianCalendar(myXMLDate.getYear(), myXMLDate.getMonth(), myXMLDate.getDay());
    }
}

Refs:

Upvotes: 1

Related Questions