问题
I don't know how to force read-only columns in Hibernate.
I would like to set idgroup as read only column. Even if I set insertable=false
and updatable=false
, in the hibernate SQL I can read:
Hibernate: insert into groups (description, name, account_idaccount, idgroup) values (?, ?, ?, ?)
but I would like to obtain:
insert into groups (description, name, account_idaccount) values (?, ?, ?)
Here are my classes:
@Entity
@Table(name = "groups")
public class Group implements java.io.Serializable {
private static final long serialVersionUID = -2948610975819234753L;
private GroupId id;
private Account account;
private String name;
private String description;
@EmbeddedId
@AttributeOverrides({@AttributeOverride(name = "idgroup", column = @Column(name = "idgroup", insertable = false)),
@AttributeOverride(name = "accountIdaccount", column = @Column(name = "account_idaccount", nullable = false))})
public GroupId getId() {
return id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "account_idaccount", nullable = false, insertable = false, updatable = false)
public Account getAccount() {
return account;
}
@Column(name = "description", length = 512)
public String getDescription() {
return description;
}
@Column(name = "name", nullable = false, length = 128)
public String getName() {
return name;
}
..
}
@Embeddable
public class GroupId implements java.io.Serializable {
private int idgroup;
private int accountIdaccount;
@Column(name = "idgroup", insertable= false, updatable= false)
public int getIdgroup() {
return this.idgroup;
}
@Column(name = "account_idaccount", nullable = false)
public int getAccountIdaccount() {
return this.accountIdaccount;
}
..
}
I would like to have a read only column for idgroup because I can exploit the id auto-generation of the DBMS, I do not want to use the key auto-generation in Hibernate because it is not cluster-safe.
回答1:
I think you can mark an @Column
annotation as updatable=false
回答2:
Easy: @Column(insertable = false, updatable = false)
回答3:
I was able to achieve this by using 2 DAO objects. I know it may not be preferred, but I didn't see another way around it. Setting the field to insertable=false
and updatable=false
do not remove the columns from the insert SQL so Postgres will not invoke the default
action to populate those column values.
// GroupWrite
@Entity
@Table(name = "group")
public class GroupWrite {
@Id
@Column(name = "account")
private Account account;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
/* Getters and Setters */
}
--
// GroupRead
@Entity
@Table(name = "group")
public class GroupRead {
@EmbeddedId
@Column(name = "id")
private GroupId id;
@Column(name = "account")
private Account account;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
/* Getters and Setters */
}
Then you need to use the GroupRead
when using select
queries and GroupWrite
when doing insert
or update
queries.
If you want to use attributes from both in a common way you can implement an interface that describes the overlapping fields.
public interface Group {
Account getAccount();
void setAccount(Account account);
}
public class GroupWrite implements Group {...}
public class GroupRead implements Group {...}
Hope this helps.
回答4:
The solution is using wrapper classes, such as Integer
, not primitive types like int
.
When Hibernate will get a null pointer it will delegate the generation of the id to the DBMS.
回答5:
@ReadOnlyProperty annotation will help you in this case.
来源:https://stackoverflow.com/questions/14626341/how-to-set-read-only-columns-in-hibernate