Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Java Spring relacja Many to Many

Ostatnio zmodyfikowano 2024-03-16 00:38
Autor Wiadomość
maf2
Temat założony przez niniejszego użytkownika
Java Spring relacja Many to Many
» 2024-03-16 00:01:20
Mam problem z relacja Many to Many. Chodzi o to że przy próbie zapisania owner2 dostaję bład: this.orepository.save(owner2);

Głowna klasa CardatabaseApplication.java
C/C++
@ SpringBootApplication
public class CardatabaseApplication implements CommandLineRunner {
   
private static final Logger logger = LoggerFactory.getLogger( CardatabaseApplication.class );
   
   
@ Autowired
    private CarRepository repository;
   
@ Autowired
    private OwnerRepository orepository;
   
   
public static void main( String[ ] args ) {
       
SpringApplication.run( CardatabaseApplication.class, args );
   
}
   
   
@ Override
    public void run( String ... args ) throws Exception {
       
Owner owner1 = new Owner( "John", "Johnson" );
       
Owner owner2 = new Owner( "Mary", "Robinson" );
       
       
Car car1 = new Car( "Toyota", "Camry", "Blue", "ABC123", 2020, 25000 );
       
Car car2 = new Car( "Honda", "Accord", "Red", "XYZ789", 2019, 22000 );
       
       
owner1.getCars().add( car1 );
       
owner1.getCars().add( car2 );
       
       
owner2.getCars().add( car1 );
       
this.orepository.save( owner1 );
       
this.orepository.save( owner2 ); // Ta linijka wywołuje błąd
   
}
}

Klasa Car.java:
C/C++
@ Entity
public class Car {
   
@ Id
    @ GeneratedValue( strategy = GenerationType.IDENTITY )
   
private Long id;
   
   
private String brand, model, color, registrationNumber;
   
   
private int modelYear, price;
   
   
public Car() {
    }
   
   
public Car( String brand, String model, String color, String registrationNumber, int modelYear, int price ) {
       
super();
       
this.brand = brand;
       
this.model = model;
       
this.color = color;
       
this.registrationNumber = registrationNumber;
       
this.modelYear = modelYear;
       
this.price = price;
   
}
   
   
@ ManyToMany( fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "cars" )
   
private Set < Owner > owners = new HashSet < >();
   
   
public Set < Owner > getOwners() {
       
return owners;
   
}
   
   
public void setOwners( Set < Owner > owners ) {
       
this.owners = owners;
   
}
   
   
public Long getId() {
       
return id;
   
}
   
   
public void setId( Long id ) {
       
this.id = id;
   
}
   
   
public String getBrand() {
       
return brand;
   
}
   
   
public void setBrand( String brand ) {
       
this.brand = brand;
   
}
   
   
public String getModel() {
       
return model;
   
}
   
   
public void setModel( String model ) {
       
this.model = model;
   
}
   
   
public String getColor() {
       
return color;
   
}
   
   
public void setColor( String color ) {
       
this.color = color;
   
}
   
   
public String getRegistrationNumber() {
       
return registrationNumber;
   
}
   
   
public void setRegistrationNumber( String registrationNumber ) {
       
this.registrationNumber = registrationNumber;
   
}
   
   
public int getModelYear() {
       
return modelYear;
   
}
   
   
public void setModelYear( int modelYear ) {
       
this.modelYear = modelYear;
   
}
   
   
public int getPrice() {
       
return price;
   
}
   
   
public void setPrice( int price ) {
       
this.price = price;
   
}
}

Klasa Owner.java
C/C++
@ Entity
public class Owner {
   
@ Id
    @ GeneratedValue( strategy = GenerationType.IDENTITY )
   
private Long ownerid;
   
private String firstname, lastname;
   
   
public Owner() {
    }
   
   
@ ManyToMany( fetch = FetchType.LAZY, cascade = CascadeType.ALL )
   
@ JoinTable( name = "car_owner",
   
joinColumns = { @ JoinColumn( name = "ownerid" ) },
   
inverseJoinColumns = { @ JoinColumn( name = "id" ) } )
   
private Set < Car > cars = new HashSet < >();
   
   
public Owner( String firstname, String lastname ) {
       
super();
       
this.firstname = firstname;
       
this.lastname = lastname;
   
}
   
   
public Set < Car > getCars() {
       
return cars;
   
}
   
public void setCars( Set < Car > cars ) {
       
this.cars = cars;
   
}
   
   
public Long getOwnerid() {
       
return ownerid;
   
}
   
   
public String getFirstname() {
       
return firstname;
   
}
   
   
public void setFirstname( String firstname ) {
       
this.firstname = firstname;
   
}
   
   
public String getLastname() {
       
return lastname;
   
}
   
   
public void setLastname( String lastname ) {
       
this.lastname = lastname;
   
}
   
   
public void setOwnerid( Long ownerid ) {
       
this.ownerid = ownerid;
   
}
}
P-180947
DejaVu
» 2024-03-16 00:38:47
Odpowiedź ChatGPT 4:
Błąd, który napotykasz podczas próby zapisu `owner2` do repozytorium, prawdopodobnie wynika z nieprawidłowej konfiguracji relacji Many-to-Many między encjami `Owner` i `Car`. Relacje Many-to-Many wymagają odpowiedniego zarządzania obu stronami relacji, aby Hibernate mógł poprawnie odzwierciedlić stan obiektów w bazie danych. Oto kilka sugestii, które mogą pomóc rozwiązać problem:

1. **Zarządzanie Stronami Relacji:**
   Upewnij się, że zarządzasz relacjami z obu stron. Oznacza to, że gdy dodajesz samochód do właściciela, powinieneś również dodać tego właściciela do samochodu. To jest kluczowe dla poprawnego działania relacji Many-to-Many w Hibernate.

2. **Zapisywanie Encji:**
   Hibernate może wymagać, aby obiekty były zapisane w odpowiedniej kolejności. Upewnij się, że samochody (`Car`) są zapisane w bazie danych przed zapisaniem właścicieli (`Owner`), aby klucze obce mogły być poprawnie przypisane.

3. **CascadeType.ALL:**
   Używasz `CascadeType.ALL` w obu kierunkach relacji Many-to-Many. To może prowadzić do niezamierzonych operacji kaskadowych, jak np. usuwanie wszystkich powiązanych obiektów przy usuwaniu jednego z nich. Upewnij się, że to zachowanie jest pożądane w twoim przypadku użycia. Może być konieczne zmodyfikowanie lub usunięcie tej opcji kaskadowości.

4. **Dodawanie Powiązań:**
   Zaktualizuj metodę, w której dodajesz samochody do właścicieli, aby również dodawać właścicieli do samochodów. Przykład:

   ```java
   owner1.getCars().add(car1);
   car1.getOwners().add(owner1);
   
   owner1.getCars().add(car2);
   car2.getOwners().add(owner1);

   owner2.getCars().add(car1);
   car1.getOwners().add(owner2);
   ```

5. **Zapisywanie Encji Samochodów:**
   Przed zapisaniem właścicieli, zapisz samochody (`Car`) w bazie danych. Może to wymagać dodania tymczasowego repozytorium dla samochodów lub użycia już istniejącego repozytorium samochodów:

   ```java
   this.repository.save(car1);
   this.repository.save(car2);
   ```

6. **Sprawdzenie Konfiguracji Repozytorium:**
   Upewnij się, że Twoje repozytorium `OwnerRepository` jest poprawnie skonfigurowane i nie ma w nim błędów, które mogłyby powodować problemy przy zapisie.

7. **Analiza Błędów i Logów:**
   Dokładnie przeanalizuj błędy i logi, które otrzymujesz. Mogą one zawierać kluczowe wskazówki co do przyczyny problemu. Szczególnie zwróć uwagę na wiadomości o naruszeniach integralności danych lub problemach z kluczami obcymi.

Jeśli po wykonaniu tych kroków problem będzie nadal występował, warto przyjrzeć się dokładnemu komunikatowi błędu lub stack trace'owi, aby zrozumieć, który element konfiguracji lub logiki aplikacji jest nieprawidłowy.
P-180948
« 1 »
  Strona 1 z 1