Reputation: 325
I am utterly confused by something I expected to work just out of the box. So either I am doing something totally wrong or this is just a misunderstanding.
I am trying to have a getter/setter annotation in a JPA Entity class. I sticked to an example I found on the JPA wiki (s. http://en.wikibooks.org/wiki/Java_Persistence/Basic_Attributes#Conversion). The example looks as follows:
@Entity
public class Employee {
...
private boolean isActive;
...
@Transient
public boolean getIsActive() {
return isActive;
}
public void setIsActive(boolean isActive) {
this.isActive = isActive;
}
@Basic
private String getIsActiveValue() {
if (isActive) {
return "T";
} else {
return "F";
}
}
private void setIsActiveValue(String isActive) {
this.isActive = "T".equals(isActive);
}
}
I took the clearest and cleanest spring-data-jpa example I could find: http://spring.io/guides/gs/accessing-data-jpa/.
I checked it out from git and changed their example entity class (s. https://github.com/spring-guides/gs-accessing-data-jpa/blob/master/complete/src/main/java/hello/Customer.java) to look as follows:
@Entity
public class Customer {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
protected Customer() {}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return String.format(
"Customer[id=%d, firstName='%s', lastName='%s']",
id, firstName, lastName);
}
@Transient
private boolean isActive;
@Transient
public boolean getIsActive() {
return isActive;
}
public void setIsActive(boolean isActive) {
this.isActive = isActive;
}
@Column
private String getIsActiveValue() {
if (isActive) {
return "T";
} else {
return "F";
}
}
private void setIsActiveValue(String isActive) {
this.isActive = "T".equals(isActive);
}
}
Now nothing changes. The respective String-Field does not get created. The line from the log creating the database table still looks as follows:
17:11:10.540 [main] DEBUG o.h.tool.hbm2ddl.SchemaUpdate - create table Customer (id bigint generated by default as identity, firstName varchar(255), lastName varchar(255), primary key (id))
I have absolutely no idea on what could be the reason for this. I could find not documentation that spring-data-jpa would not allow for annotations on getters.
Any help would be very, very appreciated!
Upvotes: 1
Views: 2930
Reputation: 4537
If you want it to work with the '@Transient' annotation you should do as Andrei suggests, you could add an extra field for isActiveValue but it is most important to annotate consistently otherwise you will get unpredictable behavior.
When annotating fields versus properties (getters and setters) it will make a difference.
In your case it looks like you want to do some logic in the getter hence annotating a field will likely not have the desired result. I don't particularly like the logic but understand that there is a need to annotate a getter.
Considering the logic in your code above I would simply eliminate the transient on the field altogether and put the logic with the annotations in the getters and setters.
@Entity
@Table(name = "Customer")
public class Customer {
private static final String IS_ACTIVE = "T";
private long id;
private String firstName;
private String lastName;
private String isActive = "";
protected Customer() {}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Column(unique = true, nullable = false)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Column(unique = true, nullable = false)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Column(unique = true, nullable = false)
public String getIsActive() {
return isActive;
}
public void setIsActive(String isActive) {
this.isActive = isActive;
}
@Transient
public boolean isActive() {
return isActive.equals(IS_ACTIVE);
}
@Override
public String toString() {
return String.format(
"Customer[id=%d, firstName='%s', lastName='%s']",
id, firstName, lastName);
}
}
Upvotes: 1
Reputation: 19002
I think you simply mixed the annotations: you must either annotate the fields, or the getters, but not both. Once you decided to annotate your ID field, you must annotate all the fields (and not getters), and the opposite: if you annotated your getId()
method, that you must annotate all methods.
Upvotes: 7