Платные услуги для вашего проекта
- Консалтинг и техническая поддержка
Запросы в рамках коммерческой поддержки имеют гарантированное время ответа
- Разработка на заказ
Предоставляем разработку полностью нашими рабочими ресурсами или участвуем в создании вашего проекта
- Обучение
Для быстрого и всестороннего освоения особенностей платформы, чтобы повысить продуктивность вашей команды
Haulmont
мы разрабатываем современные корпоративные решения
-
Эксперты в области разработки корпоративного ПО
-
Создатели CUBA Platform
-
Компания основана в 2008
-
300+
разработчиков
-
400+
проектов
-
Клиенты в
60+
странах
Главная
Я также столкнулся с этой проблемой, и решение, предложенное @adamo, было в основном правильным решением. Однако мне пришлось потратить много времени на детали, поэтому сейчас я пишу новый ответ, чтобы сэкономить это время для других.
Коробка
Мой случай был следующим: была таблица, которая была заполнена данными с помощью приложения. Теперь новую запись нужно было вставить вручную через SQL. После этого последовательность не синхронизировалась, и больше нельзя было вставить записи через приложение.
Решения
Как упоминалось в ответе @adamo, последовательность необходимо синхронизировать вручную. Для этого необходимо название последовательности. Для Postgres имя последовательности можно определить с помощью команды PG_GET_SERIAL_SEQUENCE. В большинстве примеров используются имена таблиц в нижнем регистре. В моем случае таблицы были созданы промежуточным программным обеспечением ORM (например, Hibernate или Entity Framework Core и т. Д.), И все их имена начинались с заглавной буквы.
В электронном письме от 2004 г. (ссылке) Я получил правильный намек.
(Предположим для всех примеров, что Foo это имя таблицы и Foo_id соответствующий столбец.)
Команда для получения названия последовательности:
SELECT PG_GET_SERIAL_SEQUENCE('"Foo"', 'Foo_id');
Итак, имя таблицы должно быть в двойных кавычках, окруженных одинарными кавычками.
1. Убедитесь, что последовательность не синхронизирована.
SELECT CURRVAL(PG_GET_SERIAL_SEQUENCE('"Foo"', 'Foo_id')) AS "Current Value", MAX("Foo_id") AS "Max Value" FROM "Foo";
Когда Current Value меньше чем Max Value, ваша последовательность не синхронизирована.
2. Исправление
SELECT SETVAL((SELECT PG_GET_SERIAL_SEQUENCE('"Foo"', 'Foo_id')), (SELECT (MAX("Foo_id") + 1) FROM "Foo"), FALSE);
Wondering how to fix PostgreSQL Error code 23505? We can help you.
One of the most common error codes with the PostgreSQL database is 23505. It can be seen along with the error message “duplicate key violates unique constraint”
Here at Bobcares, we often handle requests from our customers to fix similar PostgreSQL errors as a part of our Server Management Services. Today we will see how our support engineers fix this for our customers.
How PostgreSQL Error code 23505
At times we may get the following message when trying to insert data into a PostgreSQL database:
ERROR: duplicate key violates unique constraint
This happens when the primary key sequence in the table we’re working on becomes out of sync. And this might likely be because of a mass import process.
Here we have to manually reset the primary key index after restoring it from a dump file.
To check whether the values are out of sync, we can run the following commands:
SELECT MAX(the_primary_key) FROM the_table;
SELECT nextval('the_primary_key_sequence');
If the first value is higher than the second value, our sequence is out of sync.
We can back up our PG database and then run the following command:
SELECT setval('the_primary_key_sequence', (SELECT MAX(the_primary_key) FROM the_table)+1);
This will set the sequence to the next available value that’s higher than any existing primary key in the sequence.
To Resolve this error in VMware
When vpxd process crashes randomly after upgrading to vCenter Server 6.5 with the following error:
ODBC error: (23505) - ERROR: duplicate key value violates unique constraint "pk_vpx_guest_disk"; Panic: Unrecoverable database error. Shutting down VC
In the vpxd.log file, we can see entries similar to the one given below:
error vpxd[7F8DD228C700] [Originator@6876 sub=InvtVmDb opID=HB-host-476@72123-38e1cc31] >[VpxdInvtVm::SaveGuestNetworkAndDiskToDb] Failed to insert guest disk info for VM id = 976because of database error: "ODBC error: >(23505) - ERROR: duplicate key value violates unique constraint "pk_vpx_guest_disk";
–> Error while executing the query” is returned when executing SQL statement “INSERT INTO VPX_GUEST_DISK (VM_ID, PATH, CAPACITY, >FREE_SPACE) VALUES (?, ?, ?, ?)”
And in the postgresql.log file, you see entries similar to the one given below:
VCDB vc ERROR: duplicate key value violates unique constraint "pk_vpx_guest_disk" VCDB vc DETAIL: Key (vm_id, path)=(976, /tmp) already exists.
Steps to fix the error are given below:
vCenter Services can be given a service restart. If the starting fails to initialize the service and shows the same crash reason, we can fix this by removing the impacted guest disk entry from vCenter Server Database. This information is safe to remove as it will be re-populated from the host.
For vCenter Server with vPostgres database:
1. First, take a snapshot of the vCenter Server machine before proceeding.
2. Then connect the vCenter Database.
3. And identify the guest disk entry using the following query:
select FROM vc.vpx_guest_disk where vm_id=<vm id> and path='/tmp';For example: select FROM vc.vpx_guest_disk where vm_id='976' and path='/tmp';
4. For deleting the duplicate value we can use the following command:
delete FROM vc.vpx_guest_disk where vm_id=<vm id> and path='/tmp';
For example:
select FROM vc.vpx_guest_disk where vm_id='976' and path='/tmp';
We can get the VM id from the vpxd.log error entry
5. Finally start the Service.
We can delete the snapshot after observing the stability of the vCenter Server.
[Need assistance? We can help you]
Conclusion
In short, we saw how our Support Techs fix PostgreSQL Error code 23505 for our customers.
PREVENT YOUR SERVER FROM CRASHING!
Never again lose customers to poor server speed! Let us help you.
Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.
GET STARTED
var google_conversion_label = «owonCMyG5nEQ0aD71QM»;
#java #spring #postgresql #hibernate #one-to-many
#java #весна #postgresql #спящий режим #один ко многим
Вопрос:
Я получаю эту ошибку, когда пытаюсь обновить два объекта с помощью отношения один ко многим.
Это первый класс сущности:
package com.example.demo.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.SelectBeforeUpdate;
@Entity
@Table(name = "tags", schema = "public")
@NoArgsConstructor
@SelectBeforeUpdate
@Data
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(unique = true, nullable = false)
private Long id;
@Column(name = "tag")
private String tag;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id", nullable = false)
private Product product;
public Tag(String tag, Product product) {
this.tag = tag;
this.product = product;
}
}
Это второй класс объектов:
package com.example.demo.entity;
import com.example.demo.dto.ProductDto;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
@Entity
@NoArgsConstructor
@Table(name = "products", schema = "public")
@Data
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "name")
private String name;
@Column(name = "price")
private double price;
@Column(name = "added")
private Date added;
@OneToMany(mappedBy = "product", cascade = CascadeType.MERGE, orphanRemoval = true)
@Fetch(value = FetchMode.SELECT)
private List<Tag> tags;
public Product(final ProductDto productDto) {
this.id = productDto.getId();
this.name = productDto.getName();
this.price = productDto.getPrice();
this.added = new Date(productDto.getAdded());
this.tags = convertTagDtoToTag(productDto.getTags());
}
public List<Tag> convertTagDtoToTag(final List<String> tagDtos) {
return tagDtos
.stream()
.map(t -> new Tag(t, this))
.collect(Collectors.toList());
}
}
Этот метод, в котором я пытаюсь обновить:
public Product updateProduct(final ProductDto productDto) {
final Product product = this.productRepository.findById(productDto.getId()).map(p -> {
p.setName(productDto.getName());
p.setPrice(productDto.getPrice());
p.setAdded(new Date(productDto.getAdded()));
p.getTags().clear();
p.getTags().addAll(p.convertTagDtoToTag(productDto.getTags()));
return p;
}).orElse(null);
return this.productRepository.save(product);
}
И я получаю эту ошибку:
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "tags_pkey"
Detail: Key (id)=(1) already exists.
Я пишу этот метод, но я думаю, что есть лучший способ.
public Product updateProduct(final ProductDto productDto) {
final Product product = this.productRepository.findById(productDto.getId()).map(p -> {
p.setName(productDto.getName());
p.setPrice(productDto.getPrice());
p.setAdded(new Date(productDto.getAdded()));
updateTag(p.getTags(), p.convertTagDtoToTag(productDto.getTags()));
return p;
}).orElse(null);
return this.productRepository.save(product);
}
private void updateTag(List<Tag> serverTags, List<Tag> frontedTags) {
for (int i = 0; i < serverTags.size(); i ) {
serverTags.get(i).setTag(frontedTags.get(i).getTag());
}
}
Также у меня есть файл data.sql
INSERT INTO products (id, name, price, added) values (1, 'First product', 100, '2000-09-01');
INSERT INTO products (id, name, price, added)
values (2, 'Second product', 200, '2010-10-11');
INSERT INTO products (id, name, price, added)
values (3, 'Third product', 300, '2010-11-04');
INSERT INTO tags (id, tag, product_id)
values (1, 'tag1', 1);
INSERT INTO tags (id, tag, product_id)
values (2, 'tag2', 1);
INSERT INTO tags (id, tag, product_id)
values (3, 'tag3', 1);
INSERT INTO tags (id, tag, product_id)
values (4, 'tag4', 2);
INSERT INTO tags (id, tag, product_id)
values (5, 'tag5', 3);
Похоже, что ваш пост в основном состоит из кода; пожалуйста, добавьте еще несколько деталей.
Похоже, что ваш пост в основном состоит из кода; пожалуйста, добавьте еще несколько деталей.
Похоже, что ваш пост в основном состоит из кода; пожалуйста, добавьте еще несколько деталей.
Похоже, что ваш пост в основном состоит из кода; пожалуйста, добавьте еще несколько деталей.
Комментарии:
1. Первое, что я вижу, вы не должны очищать свои теги сущностей. Просто зациклите его и обновите входящими данными (но не трогайте идентификаторы). Если вы хотите добавить новые теги — просто создайте новые и добавьте их к существующим тегам. Во-вторых, это может быть проблемой стратегии генерации идентификаторов. Вероятно, Hibernate не видит существующий идентификатор (1) и пытается начать свою собственную последовательность с начала, которое тоже равно 1… Иногда это случается, особенно если вы заполняете таблицы образцами данных вручную или с помощью таких инструментов, как liquibase.
2. У меня есть файл data.sql
Ответ №1:
Пожалуйста, попробуйте вставить, получив таким образом значение следующего идентификатора:
INSERT INTO products (id, name, price, added)
values (
SELECT setval(pg_get_serial_sequence('products', 'id'), coalesce(max(id) 1, 1), false) FROM products,
'Second product',
200,
'2010-10-11'
);