Гибернация аннотации один ко многим родительско-дочернее удаление

#hibernate #jpa #annotations

#спящий режим #jpa #аннотации

Вопрос:

Я работаю с отношением onetomany в аннотациях JPA hibernate, вот моя таблица и сведения о классе сущности…

 Service   (entity class: ServiceRegistration.java)
=======
serviceid
servicename

channel    meta table (entity class: Channels.java)
========
channelid
channelname

service_channel   (entity class: ServiceChannels.java)
===============
seq_id
serviceid
channelid
  

Здесь таблица service_channel имеет serviceid и channelid в качестве внешних ключей.. Я могу извлекать, изменять записи.

  1. Но я не смог удалить службу и ее дочерние записи.. Если я удалю записи таблицы служб, соответствующие записи таблицы service_channel должны быть удалены. вот мои сведения о классе сущности…

  2. Кроме того, я получаю повторяющиеся записи.. скажем, если служба (service1) имеет 2 связанных канала, когда я извлекаю список служб, я вижу в списке 2 записи service1.

serviceregistration.java

  @OneToMany(fetch = FetchType.EAGER)
     @JoinTable(name = "multichannel_service_channel", joinColumns = {
     @JoinColumn(name="serviceid", unique = true) 
     },
     inverseJoinColumns = {
     @JoinColumn(name="channelid")
     }
     )
     private Set<Channels> channelsInvolved;


     @OneToMany(mappedBy="serviceRegistration")
     @Cascade(org.hibernate.annotations.CascadeType.REMOVE)
     private List<ServiceChannel> serviceChannels;
  

servicechannel.java

 @Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column private int servicechannelid;    

@ManyToOne
    @JoinColumn(name = "serviceid")
    private ServiceRegistration serviceRegistration;

@ManyToOne
    @JoinColumn(name = "channelid")
    private Channels channels;
  

channels.java

 @Id
@Column
private int channelid;

@Column
private String channelname;

@Column
private String channeldescription;

@Column
private boolean isactive;
  

Пожалуйста, помогите решить эту проблему.

Ответ №1:

Теперь вы задаете 2 вопроса.


Вы не можете удалить службу просто потому, что на нее ссылаются. Сначала вы должны удалить указанные объекты (или обновить их, чтобы служба не ссылалась).

Это означает, что вы должны сначала удалить соответствующие ServiceChannels перед удалением Service.

«Автоматическое» удаление ServiceChannel через Service может быть достигнуто каскадным типом «Удалить сироту», который является специфичной для гибернации функцией.


Я полагаю, что для дублированного списка это зависит от HQL, который вы использовали для извлечения списка. В случае, если вы подключили / подключили выбранные сервисные каналы, это приведет к дублированию записей. Вы должны либо использовать «выбрать отдельный», либо добавить отдельный преобразователь результатов, чтобы справиться с этим.

Комментарии:

1. Большое спасибо за ваш ответ, и это то, что я пробовал ….. **@ OneToMany(mappedBy=»ServiceRegistration») @Cascade(org.hibernate.annotations. CascadeType. DELETE_ORPHAN) частный список <ServiceChannel> serviceChannels; ** Я получаю сообщение об ошибке как….. Пакетное обновление вернуло неожиданное количество строк из u pdate [0]; фактическое количество строк: 0; ожидаемое: 1; вложенное исключение — org.hibernate . Исключение S taleStateException: Пакетное обновление вернуло неожиданное количество строк из update [0]; фактическое количество строк: 0; ожидаемое: 1

2. Я понятия не имею, что вы запустили, я думаю, что никто не сможет вам в этом помочь. Однако, по моему опыту, исключение StaleStateException, по-видимому, является еще одной проблемой, не связанной с этим вопросом. Можете ли вы сделать простой тест, попробовать DELETE_ORPHAN и убедиться, что вы знаете, что используете его правильно? Боюсь, у вас не только одна проблема в вашем коде, которая усложняет ваш вопрос.

Ответ №2:

Вы пытаетесь определить @ManyToMany или пытаетесь эмулировать @ManyToMany с помощью двух @ManyToOnes? Кажется, вы делаете и то, и другое, что не сработает.

У вас есть два варианта. Во-первых, @ManyToMany:

 create table service_channel (
  service_id int not null,
  channel_id int not null,
  primary key (service_id, channel_id));
  

ServiceRegistration.java

 @ManyToMany
@JoinTable(name = "service_channel",
           joinColumns = @JoinColumn(name="service_id"),
           inverseJoinColumns = @JoinColumn(name="channel_id"))
private Set<Channel> channels;
  

Channel.java

 @ManyToMany(mappedBy = "channels")
private Set<Service> services;
  

где ServiceChannel.java не существует. Во-вторых, вы можете повысить ServiceChannel до статуса сущности и смоделировать все это с помощью двух @OneToManys:

 create table service_channel (
  id int not null primary key,
  service_id int not null,
  channel_id int not null);
  

ServiceChannel.java:

 @ManyToOne
@JoinColumn(name = "service_id")
private Service service;

@ManyToOne
@JoinColumn(name = "channel_id")
private Channel channel;
  

Service.java:

 @OneToMany(mappedBy = "service")
private ServiceChannel serviceChannel;
  

Channel.java:

 @OneToMany(mappedBy = "channel")
private ServiceChannel serviceChannel;