OpenJPA交易例外

时间:2011-04-05 15:20:51

标签: java openjpa

我试图坚持一个班级的成员,BorderPoint。持久化一定数量的对象后,openJPA会抛出以下异常:

[错误] org.apache.openjpa.persistence.ArgumentException:尝试将id“0”分配给新实例“org.jason.mapmaker.shared.model.BorderPoint@3134a2”失败; L1缓存中已有一个具有此id的对象。在重用其ID之前,您必须删除此对象(在先前的事务或当前事务中)。当水平或垂直映射的类使用自动增量应用程序标识并且不使用应用程序标识类的层次结构时,也会发生此错误。

持久化BorderPoints的方法接受BorderPoint对象的List并尝试将persist分解为批次。这是代码:

public void persistList(List<BorderPoint> objectList) throws RepositoryException {

    EntityManager em = entityManagerFactory.createEntityManager();

    try {
        em.getTransaction().begin();
        int i = 1;
        for (BorderPoint bp : objectList) {
            em.persist(bp);
            if (i % 100 == 0) {
                em.flush();
                em.clear();
            }
            i++;
        }
        em.getTransaction().commit();
    } catch (EntityExistsException ex) {
        // need to log this somehow
        //log.warning("persist() threw EntityExistsException: " + ex.getMessage());
        ex.printStackTrace();
        throw new RepositoryException(ex);
    }
    catch (Exception e) {
        e.printStackTrace();
    } finally {
        em.close();
    }
}

为了完整起见,这是调用方法:

/**
 * Cycle through and save the borderpoints saved in the Shapefile's geometry
 *
 * @param featureCollection
 * @throws ServiceException
 */
private void saveBorderPoints(FeatureCollection featureCollection) throws ServiceException {

    FeatureIterator iterator = featureCollection.features();
    while (iterator.hasNext()) {

        SimpleFeatureImpl feature = (SimpleFeatureImpl) iterator.next();

        String geoId = (String) feature.getAttribute("GEOID10");

        Location location = locationRepository.getByGeoId(geoId);
        if (location == null) {
            throw new ServiceException("saveBorderPoints() threw ServiceException due to null Location");
        }
        MultiPolygon multiPolygon = (MultiPolygon) feature.getDefaultGeometry();
        Geometry geometry = multiPolygon.getBoundary();

        // Create the result list. Set initial capacity size to number of actual points in the geometry to avoid some
        // overhead when dealing with the list
        List<BorderPoint> borderPointList = new ArrayList<BorderPoint>(geometry.getNumPoints());

        // cycle through the coordinates to create the border points
        Coordinate[] coordinates = geometry.getCoordinates();
        for (Coordinate c : coordinates) {
            BorderPoint borderPoint = new BorderPoint();
            borderPoint.setLocation(location);
            borderPoint.setLng(new BigDecimal(c.x));
            borderPoint.setLat(new BigDecimal(c.y));

            borderPointList.add(borderPoint);
        }

        try {
            borderPointRepository.persistList(borderPointList);
        } catch (RepositoryException e) {
            throw new ServiceException("saveBorderPoints() threw RepositoryException", e);
        }
    }

    iterator.close();
}

有任何想法吗?

编辑:

这是BorderPoint类,按要求:

@Entity
@Table(name = "BORDERPOINT")
public class BorderPoint implements Serializable {

private Long id;
private Location location;
private BigDecimal lat;
private BigDecimal lng;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@Column(name="LAT")
public BigDecimal getLat() {
    return lat;
}

public void setLat(BigDecimal lat) {
    this.lat = lat;
}

@Column(name="LNG")
public BigDecimal getLng() {
    return lng;
}

public void setLng(BigDecimal lng) {
    this.lng = lng;
}

@ManyToOne(cascade = CascadeType.ALL, targetEntity = Location.class)
@JoinColumn(name="LOCATIONID")
public Location getLocation() {
    return location;
}

public void setLocation(Location location) {
    this.location = location;
}

}

0 个答案:

没有答案