Frage

Diese Frage ist ähnlich wie diese anderen

War es hilfreich?

Lösung

Kurze Antwort ist, dass Sie dies nicht tun können.

Aber eine ist hier Lösung für Ihr Problem geeignet sein kann:

In Entität A noch Bezug auf Einheit B als Liste definiert (oder sogar besser als Set, so dass die gleiche B nicht mehr enthalten sein als einmal).

@OneToMany(mappedBy="a")
private Set<B> bs;

Wie Sie wollen nicht auf die Ebene Liste, auslassen Getter und Setter für as belichten.

Dann können Sie einen Getter definieren für Sie Karte, dass die Karte im laufenden Betrieb baut:

// a transient field to cache the map
private transient Map<String, B> bsMappedByCName;

public Map<String, B> getBsMappedByCName() {
  if(bsMappedByCName == null) {
    bsMappedByCName = new HashMap<String, B>();
    for(B b : bs) {
      mapB(b);
    }
  }
  // return as unmodifiable map so that it is immutable for clients
  return Collections.unmodifiableMap(bsMappedByCName);
}

private void mapB(B b) {
  // we assume here that field c in class B and likely also field name in class C are not nullable. Further more both of this fields sould be immutable (i.e. have no setter).
  if(bsMappedByCName.put(b.getC().getName(), b) != null) {
    // multiple bs with same CName, this is an inconsistency you may handle 
  }      
}

Die letzte Ausgabe-Adresse ist, wie wir ein neues B nach A hinzufügen oder ein entfernen. Mit der Strategie, die Karte als nicht änderbar zurückzukehren, müssen wir einige Add- und Entferner Methoden in der Klasse A bieten:

public void addB(B b) {
  bs.add(b);
  mapB(b);
}

public void removeB(B b) {
  bs.remove(b);
  bsMappedByCName.remove(b.getC().getName());
}

Eine andere Option ist return Collections.unmodifiableMap(...) zu ersetzen (inspiriert von ObservaleCollection von Apache ):

return new Map<String, B>() {
  // implement all methods that add or remove elements in map with something like this
  public B put(String name, B b) {
    // check consistency
    if(!b.getC().getName().equals(name)) { 
      // this sould be handled as an error
    }
    B oldB = get(name);
    mapB(b);
    return oldB;
  }

  // implement all accessor methods like this
  public B get(String name) {
    return bsMappedByCName.get(name);
  }

  // and so on...
};

Andere Tipps

ich eine Lösung für Ihre Prämie haben. Und es funktioniert wirklich für mich.

Dies ist ein Spielzeug Beispiel arbeitet mit einer kleineren deprecation Warnung auf @CollectionOfElements. Vielleicht haben Sie sie überwinden, indem es mit einer neueren Anmerkung, dass ersetzt ihn zu ersetzen.

package com.wladimir.hibernate;

import java.util.HashMap;
import java.util.Map;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;

import org.hibernate.annotations.CollectionOfElements;

@Entity
public class A {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @CollectionOfElements
    @JoinTable
    private Map<String, B> bs = new HashMap<String, B>();

    public A() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Map<String, B> getBs() {
        return bs;
    }

    public void setBs(Map<String, B> bs) {
        this.bs = bs;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "A [bs=" + bs + ", id=" + id + ", name=" + name + "]";
    }

}




package com.wladimir.hibernate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class B {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @ManyToOne
    private C c;

    @ManyToOne
    private A a;

    public B() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "B [a=" + a.getName() + ", c=" + c.getName() + ", id=" + id
                + ", name=" + name + "]";
    }

}




package com.wladimir.hibernate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class C {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    public C() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "C [id=" + id + ", name=" + name + "]";
    }
}


package examples.hibernate;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class PersistenceUtil {
    private static final SessionFactory sessionFactory;

    static {
        Log log = LogFactory.getLog(PersistenceUtil.class);

        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (HibernateException ex) {
            // Make sure you log the exception, as it might be swallowed
            log.error("Initial SessionFactory creation failed.", ex);
            throw ex;
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

}



package examples.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;

import com.wladimir.hibernate.A;
import com.wladimir.hibernate.B;
import com.wladimir.hibernate.C;

import java.util.List;

import examples.hibernate.domain.*;

public class Tester{
    private SessionFactory factory;

    public Tester(SessionFactory factory) {
        this.factory = factory;
    }

    @SuppressWarnings("unchecked")
    public void runABC(String operation) {
        Session session = factory.getCurrentSession(); // obtain/start unit of
        // work
        Transaction tx = null;
        try {
            tx = session.beginTransaction(); // start transaction

            if ("Create".equals(operation)) {
                A a = new A();
                a.setName("A " + System.nanoTime());

                C c = new C();
                c.setName("C " + System.nanoTime());
                session.save(c);


                B b = new B();
                b.setName("B " + System.nanoTime());

                b.setA(a);
                b.setC(c);

                a.getBs().put(b.getName(), b);

                session.save(b);

                B b2 = new B();
                b2.setName("B " + System.nanoTime());

                b.setA(a);
                b.setC(c);

                a.getBs().put(b.getName(), b);

                session.save(a);


            } else if ("Read".equals(operation)) {
                System.out.println("Reading data set.");
                List<A> as = (List<A>) session.createCriteria(A.class)
                        .addOrder(Order.asc("name")).list();
                for (A a : as) {
                    System.out.println(a);
                }
            }
            tx.commit(); // commit transaction & end unit of work

        } catch (RuntimeException ex) {
            if (tx != null)
                tx.rollback(); // abort transaction
            throw ex;
        }
    }


    // main application loop
    public static void main(String args[]) throws Exception {
        Tester app = new Tester(PersistenceUtil.getSessionFactory());

        String operation = null;
        if (args.length == 1) {
            operation = args[0];
        }

        app.runABC(operation);

    }
}

Wenn alle drei Klassen Einheiten sind, können Sie versuchen, es zu Karte ändern cs, ein inverses Feld aus der B Beziehung in C gesetzt und den B-A Bezug auf C-A ändern:


class A {
   // the map should have c.name as key
   @OneToMany
   private Map<String, C> cs;
   ...

   // This method is for getting the B for a key, like it was before.
   public B getB(String key) {
       return cs.get(key).getB();
   }
}

class B {

  private Long id;

  @OneToOne // Or perhaps @ManyToOne.
  private C c;
  ...
} 

class C {

  private Long id;
  private String name;

  @OneToOne(mappedBy="c") // Or perhaps maybe @OneToMany
  private B b;
  ...

  @ManyToOne(mappedby="cs")
  private A a;
} 

Ich bin der Annahme, dass die drei Klassen Einheiten sind. Wenn C ein Fähiges ist, so dass ich weiß nicht, was zu tun ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top