Update of joined table index despite CascadeType.REMOVE [message #1743947] |
Tue, 20 September 2016 19:30  |
Eclipse User |
|
|
|
Looking at logs of an update operation, I am surprised to see an Update of join column in a child table after an update to the master table.
The log in summary is:
[EL Fine]: sql: 2016-09-20 10:07:26.312--ClientSession(618695625)--Connection(1606529584)--SELECT LAYERID, etc FROM LAYER WHERE (LAYERID = ?)
Fine - fetch the master object before update.
Connection(1606529584)--SELECT QFIELDID, layerid, NAME, etc FROM QFIELDS WHERE (layerid = ?)
Also fine, fetch any existing child rows (there arent any)
Connection(1606529584)--SELECT QFIELDS_SEQ.NEXTVAL FROM DUAL
Get a unique id for the new child row it is going to insert.
Connection(1606529584)--INSERT INTO QFIELDS (QFIELDID, layerid, NAME, etc) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Good. But then:
Connection(1606529584)--UPDATE QFIELDS SET layerid = ? WHERE (QFIELDID = ?)
What???? This is harmless (mostly - I discovered this fixing a data issue)
The modelling in JPA is:
@MappedSuperclass
@Cache (expiry=60000)
public abstract class Layer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="LibSeq")
@SequenceGenerator(name="LibSeq",sequenceName="LIBRARY_SEQ",allocationSize=1)
@Column(name = "LAYERID")
private Long layerid;
etc.
actual instance: - note the CascadeType is REMOVE
@QueryEntity
@Entity
@Table(name = "LAYER")
public class LayerAdmin extends Layer implements Serializable {
@OneToMany(fetch=FetchType.LAZY, [b]cascade=CascadeType.REMOVE[/b])
@JoinColumn(name = "layerid")
// @JsonManagedReference
private List<QfieldsAdmin> qfieldsList = new ArrayList<QfieldsAdmin>(0);
The associated child object:
@MappedSuperclass
@Cache (expiry=60000)
public abstract class Qfields implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Column(name = "QFIELDID")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="qfieldSeq")
@SequenceGenerator(name="qfieldSeq",sequenceName="QFIELDS_SEQ",allocationSize=1)
private Long qfieldid;
@Size(max = 40)
@Column(name = "NAME")
@Column (name = "LAYERID")
private Long layerid;
etc (The actual instance of the abstract class just associates with a particular table).
|
|
|
Re: Update of joined table index despite CascadeType.REMOVE [message #1744265 is a reply to message #1743947] |
Fri, 23 September 2016 14:29  |
Eclipse User |
|
|
|
Your setup is non-standard, in that the Qfields class is using a basic mapping for the LayerId foreign key instead of using a ManyToOne relationship mapping. Because it doesn't have the 'mappedby' you seem to have added the @JoinColumn annotation to specify the foreign key relationship: this @JoinColumn annotation tells the provider how to set the foreign key when the relationship is set. Since the foreign key is mapped both as a writable basic mapping, you essentially have two writable mappings to the QFIELDS.LAYERID field - JPA will update this field with the value in the Qfields.layerid attribute AND with a value from the qfieldsList list.
You need to mark one of them as insertable=false, updatable=false. The better choice will be the @JoinColumn, as it will avoid the extra update statement.
|
|
|
Powered by
FUDForum. Page generated in 0.03065 seconds