2017-02-04 1 views
0

Je travaille sur un projet où je récupèrerai la latitude et la longitude d'un utilisateur. De cela, je voudrais le stocker dans la base de données en tant que point. Cependant, lorsque je tente de le faire, j'ai couru dans l'erreur suivante: o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: Invalid endian flag value encountered.Mappage à com.vividsolutions.jts.geom.Point drapeau invalide invalide

Je prends le modèle qui est exposé à côté client et la cartographie comme suit:

public static Point createPoint(double longitude, double latitude){ 
     GeometryFactory gf = new GeometryFactory(); 

     Coordinate coord = new Coordinate(longitude, latitude); 
     Point point = gf.createPoint(coord); 

     return point; 
    } 

donc je qualifierais ce méthode à peu près comme suit pour mapper la valeur en tant que point:

createPoint(user.getLocation().getLongitude(), user.getLocation().getLatitude()); 

Ce que je stockerait alors la valeur retournée dans la base de données.

Mon fichier pom a les dépendances suivantes:

<dependency> 
     <groupId>com.vividsolutions</groupId> 
     <artifactId>jts</artifactId> 
     <version>1.13</version> 
    </dependency> 
    <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-spatial</artifactId> 
      <version>5.2.4.Final</version> 
       <exclusions> 
        <exclusion> 
         <artifactId>postgresql</artifactId> 
         <groupId>postgresql</groupId> 
        </exclusion> 
       </exclusions> 
    </dependency> 

configuration JPA:

jpa: 
     database: POSTGRESQL 
     open-in-view: false 
     show-sql: true 
     hibernate: 
      ddl-auto: none 
      dialect: org.hibernate.spatial.dialect.postgis.PostgisDialect 
      naming: 
       naming-strategy: org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy 

définition de la colonne:

@Column(name="point") 
private com.vividsolutions.jts.geom.Point point; 

Toutes les idées sur la façon dont je peux corriger cette erreur? Merci les gars d'avance.

+1

Je ne sais pas si compris votre correctyl, mais pas 'javax.persistence.AttributeConverter' ce que vous êtes à la recherche pour? – Artegon

Répondre

1

Il y a plusieurs façons d'accomplir cela et tout dépend de la façon précise dont vous souhaitez que les données soient stockées dans le magasin de données sous-jacent.

Comme indiqué dans les commentaires, vous pouvez utiliser une implémentation AttributeConverter pour stocker les x, y et z composantes des coordonnées de Point dans une seule colonne délimitée par un caractère magique:

public class PointerConverter implements AttributeConverter<Point, String> { 
    @Override 
    public String converToDatabaseColumn(Point point) { 
    // read the x, y, z, construct a string delimited by some character and 
    // return the value. Hibernate will store this in your column. 
    } 

    @Override 
    public Point convertToEntityAttribute(String value) { 
    // split the value by the delimiter and construct a Point. 
    // return the constructed Point to be set in the entity. 
    } 
} 

L'un des problèmes inhérents à cette approche est qu'elle rend presque impossible l'interrogation des différentes parties des coordonnées de Point.

Si vous trouvez que vous devez être en mesure d'interroger contre un Point et de fournir les différents x, y ou z valeurs qui composent considérant les coordonnées du Point alors vous serez mieux:

  • Une implémentation personnalisée UserType
  • En utilisant un @Embeddable pour représenter votre Point dans le monde de la persistance.

Pour une coutume UserType, vous aurez besoin de définir un nouveau type, probablement appelé PointType dans cet exemple qui va UserType, et la référence comme les suivantes:

@Type(type = "PointType") 
@Columns({@Column(name = "X"), @Column(name="Y"), @Column(name="Z")) 
private Point point; 

La coutume UserType gérerait mappage des portions x, y et z des coordonnées du point aux colonnes appropriées X, Y et Z et vice versa.

Pour une solution @Embeddable, vous voulez simplement créer votre propre classe JpaPoint que vous pouvez passer dans la géométrie Point classe pour lire les x, y et z valeurs et stocker ces données dans 3 propriétés pour le modèle de persistance. La classe JpaPoint pourrait alors exposer aussi une méthode d'assistance permettant à l'appelant de générer un Point de la JpaPoint intégrable:

// ctor example 
public JpaPoint(Point point) { 
    this.x = point.getCoordinates().x; 
    this.y = point.getCoordinates().y; 
    this.z = point.getCoordinates().z; 
} 

// helper method 
@Transient 
public Point getPoint() { 
    return new Point(new Coordinates(x, y, z)); 
} 
+0

Merci beaucoup pour votre réponse en profondeur. J'ai également essayé de créer une autre classe utilitaire pour faire la conversion de lon/lat en un point 'com.vividsolutions.jts.geom.Point 'en utilisant un WKTReader & writer et toujours pas de chance. Je vais jouer avec votre dernière idée et plutôt créer un point intégrable comme vous l'avez suggéré - cela devrait faire l'affaire. Merci encore! – Dayna

+0

S'il vous plaît, pouvez-vous mettre votre AttributeConverter pour JPAPoint (Embeddable) à Point (vividsolutions)? Je vous remercie – joseaio