#postgresql #crud #quarkus-panache
#postgresql #crud #quarkus-panache
Вопрос:
Я пытаюсь создать веб-приложение CRUD с помощью Quarkus Panache CRUD с PostgreSQL. У меня есть какой-то объект Pays, PaysDTO и ресурс PaysResource. все работает хорошо, кроме метода AddPays: в сущности Pays:
import io.quarkus.hibernate.reactive.panache.Panache;
import io.quarkus.hibernate.reactive.panache.PanacheEntityBase;
import io.quarkus.panache.common.Sort;
import io.smallrye.mutiny.Uni;
import javax.persistence.*;
import javax.transaction.Transactional;
import java.time.Duration;
import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
@Entity
@Table(name = "pays")
public class Pays extends PanacheEntityBase {
...
@Transactional
public static Uni<Pays> addPays(Pays pays){
return Panache
.withTransaction(pays::persist)
.replaceWith(pays)
.ifNoItem()
.after(Duration.ofMillis(10000))
.fail()
.onFailure()
.transform(t-> new IllegalStateException(t));
}
...
}
В PaysResource.java:
import io.smallrye.mutiny.Uni;
import org.advplan.entity.Pays;
import javax.transaction.Transactional;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import java.net.URI;
import java.util.List;
@Path("/api/pays")
public class PaysResource {
...
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Uni<Response> addOnePays(Pays pays){
return Pays.addPays(pays)
.onItem()
.transform(id -> URI.create("/api/pays/" id.id))
.onItem()
.transform(uri-> Response.created(uri))
.onItem()
.transform(Response.ResponseBuilder::build);
}
@PUT
@Path("{id}")
public Uni<Response> updateOnePays(Long id, Pays pays){
return pays.updatePays(id,pays)
.onItem().transform(entity -> entity != null ? Status.OK : Status.NOT_FOUND)
.onItem().transform(status -> Response.status(status).build());
}
...
}
При попытке добавить платит с:
curl -v --location 'localhost:8080/api/pays'
--header 'Content-Type: application/json'
--data-raw '{
"id": 221,
"npays": "SENEGAL",
"abbrevisation": "SEN",
"createdat":"2021-12-08",
"updatedat":"2021-12-08"
}'
или
% curl -v -d '{"id": 221, "npays": "SENEGAL","abbreviation":"SEN","createdat":"2021-12-08","updatedat":"2021-12-08"}' -H "Content-Type: application/json" http://localhost:8080/api/pays/
У меня такая ошибка:
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /api/pays HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 129
>
* upload completely sent off: 129 out of 129 bytes
< HTTP/1.1 500 Internal Server Error
< Content-Type: application/json
< transfer-encoding: chunked
<
* Connection #0 to host localhost left intact
{"exceptionType":"java.lang.IllegalStateException","code":500,"error":"javax.persistence.PersistenceException: org.hibernate.HibernateException: java.util.concurrent.CompletionException: org.hibernate.PersistentObjectException: detached entity passed to persist: org.advplan.entity.Pays"}* Closing connection 0
На Postman:
{
"exceptionType": "java.lang.IllegalStateException",
"code": 500,
"error": "javax.persistence.PersistenceException: org.hibernate.HibernateException: java.util.concurrent.CompletionException: org.hibernate.PersistentObjectException: detached entity passed to persist: org.advplan.entity.Pays"
}
Я пытаюсь понять, как я могу решить эту ошибку.
Вдохновленный этим уроком
https://medium.com/geekculture/creating-a-crud-shopping-service-with-quarkus-hibernate-orm-panache-and-postgresql-using-active-41a755693f12
Ответ №1:
У меня было решение моей проблемы. Эта ошибка возникает из-за того, что я предоставил данным ‘Id‘, в то время как они генерируются PanacheEntityBase автоматически. Действительно, раздел:
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
@Column (name = "id", nullable = false)
public Long id;
оставляет управление идентификатором в panache. Поэтому, когда я предоставляю данные без «идентификатора», как это:
curl -v --location 'localhost:8080/api/pays'
--header 'Content-Type: application/json'
--data-raw '{
"npays": "SENEGAL",
"abbrevisation": "SEN",
"createdat":"2021-12-08",
"updatedat":"2021-12-08"
}'
Все хорошо.
Спасибо