openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Heath Thomann <jpahe...@gmail.com>
Subject Re: Help Persisting a List
Date Mon, 11 Apr 2011 17:55:23 GMT
In addition to Mike's question, I'd like to know what version of OpenJPA you
are using.  I've seen this issue before and fixed it with JIRA OJ-1665.  I
did notice your BorderPoint class uses an '@GeneratedValue' so it appears
you are using auto generated values as described in OJ-1665.  This JIRA was
recently fixed in OpenJPA versions 1.2.x/1.3.x/2.0.x so unless you have a
recent build, you've not picked up the change yet.

Thanks,

Heath

On Wed, Apr 6, 2011 at 10:30 AM, Michael Dick <michael.d.dick@gmail.com>wrote:

> I'm going to ask Risk's standard question, how are you doing enhancement?
>
> Can you narrow down the scope of the problem, e.g. does the problem happen
> on every insert, or is it something that only happens when the list is
> large?
>
> -mike
>
>
> On Tue, Apr 5, 2011 at 4:28 PM, Jason Ferguson <fergusonjason@gmail.com
> >wrote:
>
> > I have two Entities: Location and BorderPoint. Location contains a
> > List of BorderPoint, with a bidirectional mapping between them. The
> > list containing the BorderPoints can be quite large (9,000 is not
> > unheard of). Unfortunately, the attempt to persist a list fails with
> > the following exception:
> >
> > [ERROR] org.apache.openjpa.persistence.ArgumentException: Attempt to
> > assign id "0" to new instance
> > "org.jason.mapmaker.shared.model.BorderPoint@3134a2" failed; there is
> > already an object in the L1 cache with this id. You must delete this
> > object (in a previous transaction or the current one) before reusing
> > its id. This error can also occur when a horizontally or vertically
> > mapped classes uses auto-increment application identity and does not
> > use a hierarchy of application identity classes.
> >
> >
> > I read the data from an ESRI Shapefile in two passes. The first pass
> > persists all locations in the Shapefile, then I come back and read the
> > geometry stored in the Shapefile into the BorderPoint list. The code
> > to actually persist the List of BorderPoint objects tries to break up
> > the commit into batches of 100.
> >
> > The call to persist the Locations and BorderPoint objects looks like
> this:
> >
> >        for (String typeName : typeNames) {
> >
> >            FeatureSource featureSource;
> >            FeatureCollection featureCollection;
> >
> >            try {
> >                featureSource = dataStore.getFeatureSource(typeName);
> >                featureCollection = featureSource.getFeatures();
> >
> >                saveLocations(featureCollection);
> >                saveBorderPoints(featureCollection);
> >
> >            } catch (IOException e) {
> >                throw new ServiceException("processShapefile() threw
> > IOException", e);
> >            }
> >
> >        }
> >
> > The method to persist the borderPoints looks like this:
> >
> >    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();
> >    }
> >
> > and
> >
> >    @Transactional
> >    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();
> >        }
> >    }
> >
> > Finally, here is the code for the BorderPoint class:
> >
> > @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;
> >    }
> > }
> >
> > Can anyone help me?
> >
> > Jason
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message