gpt4 book ai didi

postgresql - JPA 与很多 child 建立父/子关系

转载 作者:行者123 更新时间:2023-11-29 13:57:33 25 4
gpt4 key购买 nike

我正在尝试使用 JPA 方法创建存储实体 Track 和子实体 TrackPoints。然而,存储 Track 及其子元素 TrackPoints 会持续很长时间 - 大约 30 秒。我尝试了 GenerationType.IdentityGenerationType.SEQUENCE。如果我还有 Hibernate Spatial (Postgis) 列,它会持续更长时间——大约 60 秒来存储父项和所有子项。 JPA 按顺序发送插入,一个接着另一个。我该如何优化呢?谁能告诉我主要问题是什么?

技术:

  • Wildfly 8.1、JPA 2.1(休眠)、Hibernate Spatial、EJB、JTA
  • PostgreSQL 9.3 + PostGis - 默认设置(只需从 Ubuntu 软件包安装)

Track.java

@Entity
@Table(name = "TRACKS")
public class Track implements Serializable {
@Id
@Column(name = "track_id", nullable = false, unique = true)
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;

@NotNull
@NotEmpty
@Size(min = 1, max = 100)
@Column(nullable = false, length = 100)
private String name;

@Size(max = 200)
@Column(nullable = false, length = 200)
private String description;

@OneToOne(optional = false)
@JoinColumn(name = "userId", nullable = false)
private User userOwner;

@NotNull
@NotEmpty
@Column(nullable = false, length = 55)
private String type;

@NotNull
private Boolean isShared;

@OneToMany(mappedBy = "track")
private List<TrackPoint> trackPoints;
}

TrackPoint.java

@Entity
@Table(name = "TRACK_POINTS")
public class TrackPoint implements Serializable {

private static final long serialVersionUID = 8089601593251025235L;

@Id
@Column(name = "trackpoint_id", nullable = false, unique = true)
@GeneratedValue(generator = "track_point_sequence", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "track_point_sequence", sequenceName = "track_point_sequence", allocationSize = 1000)
private Long id;

@NotNull
private int trackSegment;

@NotNull
private double elevation;

@NotNull
@Temporal(TemporalType.TIMESTAMP)
private Date timeStamp;

@NotNull
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "track_id")
private Track track;

/*Hibernate Spatial - Postgis field.
@NotNull
@Column(nullable = false)
@Type(type = "org.hibernate.spatial.GeometryType")
private Geometry location;*/
}

TrackService.java

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class TracksService implements ITracksService {

@Inject
private IDaoService dao;

@Override
public Long createTrack(GpxType gpx, String userId, String name, String desc) {
// Map GPX to Track, TrackPoint object.
track = dao.create(track);

int batch_size = 50;

int i = 0;

for(TrackPoint point: track.getTrackPoints()) {
dao.create(point);
if(i++ % batch_size == 0) {
dao.flush();
dao.clear();
}
}

return track.getId();

}

DaoService.java

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class DaoService implements IDaoService {

@PersistenceContext()
private EntityManager em;

@Override
public <T extends Serializable> T create(T t) {
em.persist(t);
return t;
}
}

persistence.xml

<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xsi:schemaLocation=
"http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">

<persistence-unit name="postgisTourbookPU" transaction-type="JTA">

<description>PostgresSQL database with PostGIS extension</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>${tourbook.datasource.postgresql.jndi-name}</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>

<properties>
<!-- JPA properties -->
<property name="javax.persistence.schema-generation.database.action"
value="drop-and-create"/>

<!-- <property name="javax.persistence.schema-generation-target"
value="database"/>-->

<!-- Creation Schema Properties -->
<property name="javax.persistence.schema-generation.create-source"
value="metadata"/>

<!-- &lt;!&ndash; DDL Script location, when script is used &ndash;&gt;
<property name="javax.persistence.schema-generation.create-script-source"
value="META-INF/create-script.sql"/>-->

<!-- Drop Schema Properties -->
<property name="javax.persistence.schema-generation.drop-source"
value="metadata"/>
<!-- <property name="javax.persistence.schema-generation.drop-script-source"
value="META-INF/drop-script.sql"/>-->

<property name="javax.persistence.sql-load-script-source"
value="META-INF/load-script.sql"/>

<!-- JPA driver information -->
<property name="javax.persistence.jdbc.driver"
value="org.postgresql.Driver"/>

<!-- Hibernate properties -->
<property name="hibernate.connection.characterEncoding"
value="UTF-8"/>

<property name="hibernate.dialect"
value="org.hibernate.spatial.dialect.postgis.PostgisDialect"/>

<property name="hibernate.default_schema"
value="public"/>

<property name="hibernate.show_sql"
value="true"/>

<property name="hibernate.jdbc.batch_size" value="50"/>

<property name="hibernate.jdbc.fetch_size"
value="50"/>

<property name="hibernate.order_inserts"
value="true"/>

<property name="hibernate.order_updates"
value="true"/>

<property name="hibernate.cache.use_query_cache"
value="false"/>

<!-- Hibernate caching -->

</properties>
</persistence-unit>
</persistence>

已编辑

所以我已经尝试过,在Hibernate中批量插入,但我仍然有30秒的时间来保存2000点。

最佳答案

您要插入一个包含所有子项的父项。在那种情况下,Hibernate JPA 确实会很慢,但是有一些技巧可以提高性能- 查看休眠批处理指南 http://docs.jboss.org/hibernate/core/4.0/devguide/en-US/html/ch04.html- 我使用了 hibernate.jdbc.batch_size 参数(例如设置为 50)

祝你好运 加布里埃尔

关于postgresql - JPA 与很多 child 建立父/子关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28497271/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com