Customizing HATEOAS link-Generierung für Personen mit composite ids
Ich so konfiguriert haben, dass ein RepositoryRestResource
auf eine PageAndSortingRepository
zugreift, eine Einheit, die beinhaltet ein composite-Id:
@Entity
@IdClass(CustomerId.class)
public class Customer {
@Id BigInteger id;
@Id int startVersion;
...
}
public class CustomerId {
BigInteger id;
int startVersion;
...
}
@RepositoryRestResource(collectionResourceRel = "customers", path = "customers", itemResourceRel = "customers/{id}_{startVersion}")
public interface CustomerRepository extends PagingAndSortingRepository<Customer, CustomerId> {}
Wenn ich auf den server zugreifen zu "http://<server>/api/customers/1_1"
zum Beispiel, bekomme ich die richtige Ressource wieder als json, aber die href in der _links Abschnitt für sich selbst ist, das falsche und das gleiche auch für alle anderen Kunden, die ich Abfrage: "http://<server>/api/customer/1"
d.h.:
{
"id" : 1,
"startVersion" : 1,
...
"firstname" : "BOB",
"_links" : {
"self" : {
"href" : "http://localhost:9081/reps/api/reps/1" <-- This should be /1_1
}
}
}
Ich vermute, das ist wegen meiner composite-Id, Aber ich bin chuffed, wie ich das ändern kann das Standard-Verhalten.
Hatte, habe ich einen Blick auf die ResourceSupport
und die ResourceProcessor
Klasse, aber bin mir nicht sicher, wie viel ich ändern muss, um dieses Problem zu beheben.
Kann jemand, der weiß, Feder Leih mir eine hand?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Leider alle Spring-Data-JPA/Rest bis Version 2.1.0.RELEASE sind nicht in der Lage, zu dienen, Ihren Bedarf aus der box.
Die Quelle wird begraben inside Spring Data Commons/JPA selbst. Spring Data JPA unterstützt nur
Id
undEmbeddedId
als Bezeichner.Auszug
JpaPersistentPropertyImpl
:Spring Data Commons nicht unterstützen das Konzept der kombinierten Eigenschaften. Er behandelt jede Eigenschaft einer Klasse unabhängig voneinander.
Natürlich können Sie hack Spring Data Rest. Aber dies ist mühsam, nicht das problem löst, in Ihrem Herzen und reduziert die Flexibilität des Frameworks.
Hier ist der hack. Dies sollte Ihnen eine Idee geben, wie Sie zur Bewältigung Ihres Problems.
In Ihrer Konfiguration überschreiben
repositoryExporterHandlerAdapter
und zurückgebenCustomPersistentEntityResourceAssemblerArgumentResolver
.Darüber hinaus überschreiben
backendIdConverterRegistry
und fügen SieCustomBackendIdConverter
zu der Liste der bekanntenid converter
:Erstellen
CustomBackendIdConverter
. Diese Klasse ist verantwortlich für die Darstellung Ihrer benutzerdefinierten Entität ids:CustomPersistentEntityResourceAssemblerArgumentResolver
wiederum zurückgeben sollte eineCustomPersistentEntityResourceAssembler
:CustomPersistentEntityResourceAssembler
muss überschreibengetSelfLinkFor
. Wie Sie sehen könnenentity.getIdProperty()
wieder entweder id oder startVersion Eigentum IhrerCustomer
- Klasse, die wiederum wird verwendet, um den realen Wert, der mit Hilfe einesBeanWrapper
. Wir sind hier zu einem Kurzschluss der ganze Rahmen mit dem Einsatz voninstanceof
Betreiber. Damit IhreCustomer
Klasse implementieren sollteSerializable
für die weitere Verarbeitung.Das ist es! Sie sollten sehen, diese URIs:
Imho, wenn man auf einem grünen Feld-Projekt würde ich vorschlagen, zu Graben
IdClass
vollständig und gehen mit technisch einfachen ids, basierend auf Lang-Klasse. Getestet wurde dies mit Spring Data Rest 2.1.0.RELEASE, Spring data JPA 1.6.0.RELEASE-und Spring-Framework 4.0.3.RELEASE.fromRequestId
Deserialisieren Ihre ids.Zwar nicht wünschenswert, ich habe gearbeitet, um dieses Problem durch die Verwendung eines
@EmbeddedId
statt einerIdClass
Anmerkung auf meine JPA-entity.Etwa so:
Jetzt sehe ich die korrekt generierten links
1_1
auf meinem zurückgegebenen Entitäten.Wenn jemand noch mir eine Lösung, die nicht erfordert, ändere ich die Darstellung meines Modells, Es würde sehr geschätzt werden. Zum Glück hatte ich nicht weit Fortgeschritten in meiner Anwendung Entwicklung um dies zu ernsthaften Bedenken in wechselnden, aber ich kann mir vorstellen, dass für andere, es würde zu einem erheblichen Mehraufwand bei der Durchführung einer änderung wie diese: (z.B. Wechsel alle Abfragen, die die Referenz dieses Modells in JPQL-queries).
@Transient
zu einemgetKey
Methode, die zurückid.key
imCustomer
dass können Sie haben einen schnellen Zugriff in der API aber wird nicht auf Ihre ERHOLUNG Darstellung. Es ist hässlich, aber macht Ihr API-Reiniger.Ich hatte ein ähnliches problem, wo der zusammengesetzte Schlüssel Szenarien für die data rest war nicht arbeiten. @ksokol ausführliche Erklärung, sofern die notwendigen inputs, um das Problem zu lösen. geändert, meine pom in Erster Linie für Daten-Erholung-webmvc und Daten-jpa als
die Lösung all der Fragen, die mit einem zusammengesetzten Schlüssel und ich brauche nicht die Anpassung. Dank ksokol für die ausführliche Erklärung.
Erstellen Sie zunächst eine SpringUtil zu bekommen bean von spring.
Dann, implementieren BackendIdConverter.
Danach. Sie können tun, was Sie wollen.
Es ist ein Beispiel unten.
localhost:8080/demo/1 als normal. Nach meinem code nehme an der pk
hat eine annotation "@Id".
die annotation "@EmbeddedId", können Sie localhost:8080/demo/{demoId
json} to get/put/delete. Und dein selbst wird der link der gleiche ist.