Reputation: 813
Toplink can use read-only mappings when multiple attributes in an object map to the same fields in the database but only one of the mappings can write to the field.
Does JPA has such feature, how to write annotation? I have one @ManyToOne
and one @Column
annotation which need to map to same field in database.
@ManyToOne(optional=false, fetch=FetchType.LAZY)
@JoinColumn(name="USR_ID", referencedColumnName="USER_ID", nullable=false)
private User user;
/** @generated **/
@Column(name="USER_ID", nullable=false, length=30)
private String userId;
Upvotes: 21
Views: 31114
Reputation: 48853
updatable=false, insertable=false
might not be enough. Hibernate exposes additional requirement:
org.hibernate.DuplicateMappingException:
Table [passenger] contains physical column name [parent_id]
referred to by multiple logical column names: [parent_id], [parentId]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl$TableColumnNameBinding.bindPhysicalToLogical(InFlightMetadataCollectorImpl.java:1055)
The logical name parent_id
comes from:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(insertable = false, updatable = false)
private Passenger parent;
while parentId
comes from:
private Long parentId;
To harmonize logical names correct one (or set both) explicitly:
@Column(name = "parent_id")
private Long parentId;
Requirements for updatable=false, insertable=false
comes from:
for ( Selectable columnOrFormula : value.getSelectables() ) {
if ( !columnOrFormula.isFormula() ) {
Column col = (Column) columnOrFormula;
if ( !distinctColumns.add( col.getName() ) ) {
throw new MappingException(
"Column '" + col.getName()
+ "' is duplicated in mapping for entity '" + getEntityName()
+ "' (use '@Column(insertable=false, updatable=false)' when mapping multiple properties to the same column)"
located:
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:1009)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:1027)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:1055)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:720)
at org.hibernate.mapping.RootClass.validate(RootClass.java:283)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:376)
Upvotes: 0
Reputation: 11113
From here
The Column annotation and XML element defines insertable and updatable options. These allow for this column, or foreign key field to be omitted from the SQL INSERT or UPDATE statement. These can be used if constraints on the table prevent insert or update operations. They can also be used if multiple attributes map to the same database column, such as with a foreign key field through a ManyToOne and Id or Basic mapping. Setting both insertable and updatable to false, effectively mark the attribute as read-only.
So
@Column(name="USER_ID", nullable=false, length=30,
updatable=false, insertable=false)
private String userId;
should do it
Upvotes: 51