i have a one to many entity association model in this way:
@Entity
@Table(name = "father")
public class Father {
@Id
@GeneratedValue
@Column(columnDefinition = "BINARY(16)", updatable = false)
@Type(type="org.hibernate.type.UUIDBinaryType")
private UUID id;
...
@OneToMany(cascade = CascadeType.ALL, mappedBy = "father", orphanRemoval = true)
private List<AbstractChild> children = new ArrayList<>();
...
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name="type",
discriminatorType = DiscriminatorType.INTEGER,
columnDefinition = "TINYINT(1) NOT NULL")
@Table(
name = "child",
uniqueConstraints = @UniqueConstraint(columnNames = {"type", "name", "father_id"})
)
@IdClass(Child.class)
public abstract class AbstractChild implements Serializable {
@Id
@Column(nullable = false)
protected Locale locale;
@Id
@ManyToOne(fetch = FetchType.LAZY)
protected Father father;
@Id
@Column(name = "type", insertable = false, updatable = false)
protected short mediaType;
...
}
@Entity
@DiscriminatorValue("1")
public class ConcreteChildOne extends AbstractChild {
@Lob
private String content;
...
}
@Entity
@DiscriminatorValue("2")
public class ConcreteChildTwo extends AbstractChild {
@Column(name = "path")
private String path;
...
}
Everything seems fine but when i save a Father entity with children, the values order in generated sql is wrong.
The insert query for the father is ok
insert
into
father
(description, name, id)
values
(?, ?, ?)
has those binding parameters
- binding parameter [1] as [VARCHAR] - [description]
- binding parameter [2] as [VARCHAR] - [name]
- binding parameter [3] as [BINARY] - [3bfac6e0-08ec-4f6b-a62a-5626ee6ab0e5]
But the insert query for the child is wrong
insert
into
tourist_informations
(content, type, father_id, locale)
values
(?, ?, ?, ?)
- binding parameter [1] as [CLOB] - [this is my content]
- binding parameter [2] as [BINARY] - [3bfac6e0-08ec-4f6b-a62a-5626ee6ab0e5]
- binding parameter [3] as [SMALLINT] - [1]
- binding parameter [4] as [VARCHAR] - [en_EN]
The sql to create database is
create table father (
id BINARY(16) not null,
description varchar(255),
name varchar(150) not null,
primary key (id)
) engine=InnoDB
create table child (
type TINYINT(1) NOT NULL ,
locale varchar(255) not null,
path varchar(255),
content longtext,
father_id BINARY(16) not null,
primary key (father_id, type, locale)
) engine=InnoDB
alter table tourist_informations
add constraint FKpem984v0clq1bsvubkkynoq7x
foreign key (father_id)
references father (id)
Someone as an idea why the order is wrong? Thank you in advice.
CodePudding user response:
I think your mapping is wrong. It should be:
@OneToMany(cascade = CascadeType.ALL, mappedBy = "father", orphanRemoval = true)
private List<AbstractChild> children = new ArrayList<>();
CodePudding user response:
I have found a map that works:
@Entity
@Table(name = "father")
public class Father {
@Id
@GeneratedValue
@Column(columnDefinition = "BINARY(16)", updatable = false)
@Type(type="org.hibernate.type.UUIDBinaryType")
private UUID id;
...
@OneToMany(cascade = CascadeType.ALL, mappedBy = "father", orphanRemoval = true)
private List<AbstractChild> children = new ArrayList<>();
...
}
@Embeddable
public class ChildID implements Serializable {
@Column(name = "type")
protected short type;
@Column(nullable = false)
protected String name;
@Column(columnDefinition = "BINARY(16)", name = "father_id")
@Type(type="org.hibernate.type.UUIDBinaryType")
private UUID fatherId;
...
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name="type",
discriminatorType = DiscriminatorType.INTEGER,
columnDefinition = "TINYINT(1) NOT NULL")
@DiscriminatorOptions(force = true, insert = false)
@Table(
name = "child",
uniqueConstraints = @UniqueConstraint(columnNames = {"type", "name", "father_id"})
)
@IdClass(Child.class)
public abstract class AbstractChild implements Serializable {
@EmbeddedId
private ChildID id;
public AbstractChild() {
this.id = new ChildID();
}
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("fatherId")
protected Father father;
...
}
@Entity
@DiscriminatorValue("1")
public class ConcreteChildOne extends AbstractChild {
@Lob
private String content;
public ConcreteChildOne() {
super();
this.getId().type = 1;
}
...
}
@Entity
@DiscriminatorValue("2")
public class ConcreteChildTwo extends AbstractChild {
@Column(name = "path")
private String path;
public ConcreteChildTwo() {
super();
this.getId().type = 2;
}
...
}
Of course you can improve the code using delegate method to set type on embedde d id or pass it with super() into constructor but those things are details.
Hope that answer can help Thank you all for your answer