I have an @Entity
containing a few @OneToMany
relationships, but since they consist of collections of Enum
s, I'm using @ElementCollection
. The entity has an id that gets generated at the database level (MySQL).
Here is a small example I just made up that corresponds to the structure of my entity.
@Entity
public class Student {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ElementCollection(targetClass = Language.class)
@CollectionTable(name="student_languages", joinColumns=@JoinColumn(name="student_id"))
private Set<Language> languages;
@ElementCollection(targetClass = Module.class)
@CollectionTable(name="student_modules", joinColumns=@JoinColumn(name="student_id"))
private Set<Module> modules;
@ElementCollection(targetClass = SeatPreference.class)
@CollectionTable(name="student_seats", joinColumns=@JoinColumn(name="student_id"))
private Set<SeatPreference> seatPreference;
[...]
}
I know that GenerationType.IDENTITY
deactivates batching, but I thought that would be the case for the main entity only, not for the single properties too. I'm havin to bulk import a few entities (~20k), each with a handful of properties, but Hibernate seems to be generating one insert for each property in the sets, making the import impossibly slow (between 10 and 20 inserts for each record).
I have now spent so long trying to make this faster, that I'm considering just generating an SQL file that I can manually import in the database.
Is there no way to instruct Hibernate to batch inserts the @ElementCollection
fields? Am I doing something wrong?
Basically, seem hibernate will not help with
@ElementCollection
batching but you can use the SQL bulk inserts. Seems you are on MySQL which does support the bulk inserts and its JDBC driver can automatically modify / rewrite the individual insert statements into one bulk statement if you enable therewriteBatchedStatements
property.So in your case what you need to do is tell hibernate to enable batching and order the batch inserts and updates.
This will ensure that when inserting the data into DB the inserts statements generated by Hibernate will be executed in a batch and they will be ordered.
So the SQL generated by Hibernate will be something like this:
Next, you will need to tell the JDBC driver to rewrite the individual inserts into the bulk insert by setting the
rewriteBatchedStatements=true
So this will instruct the driver to rewrite the inserts into bulk form, so the above several SQL statements will be rewritten into something like this
Just as an info this may not work if you are using old versions of the MySQL driver and Hibernate.