Answer the question
In order to leave comments, you need to log in
How to write calculated field from stored procedure to transient field of Entity?
Good afternoon.
There is a table in the database (Firebird), it is mapped on Entity.
A stored procedure works with this table, which returns both the field values from the table and the calculated value.
Under this calculated value in Entity, I created a Transient variable.
I made SqlResultSetMapping, in which I wrote the correspondence of the fields from the stored procedure to the fields in the Entity.
The problem is that nothing is written to the Transient field.
How can you win?
The code:
@NamedStoredProcedureQuery(
name = Building.VR,
procedureName = "VALUATION_RESULTS_VC",
resultSetMappings = "Mapping",
parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "IP_ID", type = Integer.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "P_ID", type = Integer.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "P_CLASS", type = String.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "P_CRN_VC", type = Double.class)
}
)
@SqlResultSetMapping(
name = "Mapping",
entities = @EntityResult(
entityClass = Building.class,
fields = {
@FieldResult(name = "id", column = "P_ID"),
@FieldResult(name = "name", column = "P_CLASS"),
@FieldResult(name = "crn", column = "P_CRN_VC")
}
)
)
@Access(AccessType.FIELD)
@Entity
@Table(name = "main_tab")
public class Building extends BaseEntity {
public static final String VR = "Asset.VR";
@Transient <-если убрать Transient и создать такое реальное поле в таблице, то все работает. Но это поле вычисляемое и оно в таблице не нужно.
private Double crn;
public Double getCrn() {
return crn;
}
public void setCrn(Double crn) {
this.crn = crn;
}
}
@MappedSuperclass
public abstract class BaseEntity {
@Id
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
}
Answer the question
In order to leave comments, you need to log in
By definition, a @Transient annotated field will be ignored by the ORM. In both directions: nothing will be written to the database, and it cannot be installed from the database. But you can use method
-level access . In addition to the @Column annotation, you need to put the @Access(AccessType.PROPERTY) annotation on the getter.
Since the field is calculated, it's rather strange to see setCrn(Double crn) in a class. This can confuse the ORM, and people too. I would go even further and rename getCrn to make it clear that it is a computed value.
PS In modern databases there is such a thing as a (materialized) view - a query or the result of a stored operation, the results of which can be accessed as a table. This approach is often used and has certain advantages. Probably, here the view will be a redundant solution, but for general development, I suggest looking in this direction as well.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question