Problem mit @ManyToMany und CascadeType.ALL

bluer

Aktives Mitglied
Hi Leute,

in meiner Web-App soll es möglich, dass ein Berater(Consultant) Kunden (Customer) und Projekte(Project) anlegen kann. Es gibt bei der Web-App ein User-Managment und zwar so, dass ein User entweder ein Berater ist oder ein Kunde. Zwischen der Entity User und Project ist folgende m:n-Beziehung gemappt:
Java:
...
    @ManyToMany( cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
    @JoinTable( name = "User_Project",
                     joinColumns = {@JoinColumn( name="user_id")},
                     inverseJoinColumns = {@JoinColumn (name = "project_id")})
    public List<Project> getProjects() {return this.projects; }
...
Mein Problem ist nun, dass ich bei 2 Usern die Projekte updaten muss und er sowohl beim ersten User als auch beim zweiten das neue Projekt in die DB schreibt bzw. schreiben will. Das ist natürlich nicht gewünscht. Vllt ist meine vorgehensweise nicht korrekt? Ich update bzw. persistiere zu erst den CustomerUser und anschließend den ConsultantUser. Der JavaCode sieht wie folgt aus:
ProjectWizardController.java:
Java:
...
    @Transactional
    public void finalWizard(){
        if( !this.selectedCatalog.equals(-1L))
            try{
                if( this.customer.getId() == null ){
                    this.user.setPassword(this.password);
                    this.user.addProject(project);
                    Map<String, GrantedAuthority> authorities = new LinkedHashMap<String, GrantedAuthority>();
                    this.messageController = new MessageController();
                    authorities.put(messageController.getMessage("user_role_"
                         + Role.valueOf("CUSTOMER").toString()), new GrantedAuthorityImpl(Role.valueOf("CUSTOMER").toString()));
                    this.user.setAuthorities(authorities.values());
                    User consultantUser = this.userDao.getById(this.consultant.getUser().getId());
                    consultantUser.getProjects().add(this.project);
                    this.userDao.persist(this.user, this.customer, consultantUser);
                    //this.userDao.update(consultantUser, this.project);
                }else{
                    User updateCustomer = this.userDao.getById(this.customer.getUser().getId());
                    updateCustomer.getProjects().add(this.project);
                    User updateConsultant = this.userDao.getById(this.consultant.getUser().getId());
                    updateConsultant.getProjects().add(this.project);
                    this.userDao.update(updateCustomer, updateConsultant);
                }
                this.increasePosition();
                //this.userDao.update(this.customer.getUser(), this.project);
            }catch(Exception e){
                System.out.println(e.getMessage());
            }
    }
...
UserDaoImpl:
Java:
...
    @PersistenceContext(type = PersistenceContextType.EXTENDED)
    private EntityManager em;
...
    public User update(User customer,User consultant){
            em.merge(customer);
            em.merge(consultant);
            em.flush();
            return consultant;
        }

    public void persist(User user, Customer customer, User consultant ){
            em.persist(customer);
            em.persist(user);
            em.merge(consultant);
            em.flush();
        }
...
Er versucht immer ein Project doppelt einzutragen. Wie kann ich das verhindern?
 
N

nillehammer

Gast
Zwei Stellen:
1. Implementiere eine equals()-Methode, mit der JAVA erkennt, dass zwei Project-Instanzen gleich sind.
2. In der Project-Entity definiere für die Kombination aus Spalten, die für ein Project einzigartig sein müssen, einen Unique-Constraint. Wenn Du Hibernate benutzt, kannst Du auch NaturalId benutzen
 

bluer

Aktives Mitglied
Die ProjectName-Spalte ist schon unique:
Java:
...
    @Column(unique = true)
    public String getProjectName() {
	return projectName;
    }
...
Deswegen schmeißt er mir ja die Exception, dass der Projektname schon vorhanden ist. Gibt es keine Mehtode die sowas sagt wie: Schreibe Daten nur in DB, wenn sie nicht schon existieren?! Mein Problem ist, dass er zuerst beim persistieren bzw. updaten des CustomerUser das Projekt in die DB schreibt, wg CascadeType.ALL, und anschließend das gleiche für den ConsultantUser probiert ... :bahnhof:
 

bluer

Aktives Mitglied
Habe das Problem heut morgen gelöst. Sehr hilfreich dabei, war folgende Seite: Java Persistence/ManyToMany - Wikibooks, open books for an open world :toll:
Da steht kurz geagt, dass JPA nicht zaubern kann. D.h. in meinem Fall, einer bidirektionalen m:n-Beziehung, dass man JPA schon mitteilen muss, wann was gelöscht oder hinzugefügt werden soll und es nicht reicht ein CascadeType.ALL anzufügen. DIe Lösung sieht wie folgt aus:
Java:
public class ProjectWizardController{ 
...
    public void finalWizard(){
    ...
        this.userDao.update(customerUser, consultantUser, project);
    ...
    }
...
}

public class UserDaoImpl implements Userdao{
...
    public User update(User customerUser, User consultantUser, Project project){
        em.persist(project);
        em.merge(customerUser);
        consultantUser = em.merge(consultantUser);
        em.flush();
        return consultantUser;
    }
...
}

Vielen Dnak für eure Hilfe!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A JPA - ManyToMany Problem - keine Unique Mehrfachzuweisungen Data Tier 4
N Problem beim initialisieren des Caches Data Tier 0
S JPA Problem mit Cascading Data Tier 1
M Eclipse 4 RCP Hibernate Problem Data Tier 3
C JPA FetchType.LAZY, Relation @OneToMany und Problem mit dem update Data Tier 1
K Problem mit EJBs und Transaktionen Data Tier 0
G JPA: Entity Klasse @JoinColumns Problem Data Tier 2
M JPA Problem: java.sql.SQLSyntaxErrorException: Data Tier 7
H Hibernate Problem mit Lazy Loading bei @OneToMany Collections Data Tier 5
M MySql und JPA-Timestamp Problem Data Tier 8
J Hibernate Problem bei Master-Detail-Tabellen Data Tier 5
M Problem beim Laden von Objekten, die von anderen Applikationen in eine DB eingefügt wurden Data Tier 5
M Problem mit @Temporal Mapping und SQL Server Data Tier 3
P JPA - HashMap mit Many-to-Many Relation Problem Data Tier 4
Blackskyliner [JPA][Anfänger] Problem mit Wertzuweisung aus Verbundtabelle Data Tier 2
B Problem mit org.hibernate.LazyInitializationException Data Tier 11
B DatenquellenUpdater extends Thread - Problem mit PermGenSpace Data Tier 5
S Problem beim Insert mit Hibernate Data Tier 9
Y [openJPA] Problem mit Transaktion? Data Tier 2
A @SecondaryTable Problem Data Tier 9
N Problem beim session.flush(); Data Tier 17
Y Postgres und JPA - Primärschlüssel Problem Data Tier 3
P SQL PRoblem Hibernate? Data Tier 8
Y EJB Problem mit Transaktionen Data Tier 7
M Transaction / Session Problem Data Tier 4
G JPA 2.0 Query Problem Data Tier 3
P CORBA Problem bei EJB 3.0 Anwendung in Glassfish v3 Data Tier 7
F Problem mit Hibernate Schema Update Data Tier 2
S Lazy loading Problem Data Tier 2
M Insert-Problem mit JPA/Hibernate Data Tier 4
megachucky JPA - Problem mit Persistence Unit / Context Data Tier 1
H Hibernate Problem Data Tier 4
D Performance Problem mit Prepared Statement Data Tier 6
T Problem mit openJPA Data Tier 7
P Problem mit Data Tier 9
GilbertGrape Cascade Problem (Hibernate) Data Tier 3
C JPA Problem mit attributeOverride und mehrspaltigem PK Data Tier 2
B select "neu" statement Problem (jpql) Data Tier 8
boxi Hibernate Lazy Loading Problem Data Tier 2
M Problem mit Hibernate und SLF4J - NoSuchMethodException Data Tier 3
G Connection Problem - WAS 6.1, Hibernate, OS Authentication Data Tier 1
K Hibernate update-Problem Data Tier 36
J hibernate problem Data Tier 14
N Hibernate - Problem mit Update/Insert Data Tier 4
B Problem mit @PersistenceContext Data Tier 4
G Problem with mapped of the tables at one to one relationship Data Tier 8
J Hibernate @ManyToMany: Keine Werte in der JoinTable Data Tier 0
A ManyToMany löscht zugewiesene Dateien Data Tier 1
M JPA ManyToMany mit zusätzlicher Spalte Data Tier 0
A @ManyToMany - Kein Löschen bereits zugewiesener Entities Data Tier 6
A EclipseLink JPA - ManyToMany und Select Abfrage Data Tier 8
I EJB3 @ManyToMany Data Tier 4
GilbertGrape hibernate: manyToMany primaryKey in Verknüpfungstabelle? Data Tier 2

Ähnliche Java Themen


Oben