@ManyToMany с Hibernate и JPA - PullRequest
       1

@ManyToMany с Hibernate и JPA

1 голос
/ 11 апреля 2011

У меня есть две таблицы, которые связаны отношением ManyToMany.

Таблица 1 имеет временной интервал и содержит коллекцию документов, созданных в этот временной интервал. Таблица 2 представляет собой Документы и содержит коллекцию временных интервалов, поскольку данный документ может быть изменен много раз в разных временных интервалах.

В этой конкретной программе для каждого документа я нахожу или создаю для него строку документа. Далее я нахожу или создаю временной интервал, который представляет эпоху действия, создания, обновления, удаления. Примечание: удаление - это событие, выполняемое в документе, а не в строке, которая его представляет. В этой программе нет операций удаления или удаления, выполненных для любой строки любой из таблиц.

Однако я вижу столько удалений в таблице сопоставления timeslot_document, сколько имеется вставок.

У меня такой вопрос, почему Hibernate выдает удаление? Похоже, это связано с грязной обработкой обновлений. Почему повторное удаление из временного интервала, где id = 1?

Когда у меня была OneToMany, я не видел удалений, но модель тогда была неточной (как вы можете себе представить).

Для каждого документа я определяю дату (только с точностью до часа), когда произошло действие, увеличиваю счет и добавляю документ в коллекцию.

Что-то еще любопытное - я реализую MVCC через аннотацию @Version, но в состоянии 'show innodb status \ G' я вижу таблицу заблокированной. На данный момент есть одна строка для временного интервала, в ней подсчитаны документы 1988 года, а версия строки - в 1999 году. Блокировка таблицы касается меня.

Вот основной фрагмент кода:

        for (Eventlog event : eventsList) {
            currentEvent = event.getEventId();
            String tmp = formatter.format(event.getEpoch());
            Date epoch = null;
            try {
                epoch = formatter.parse(tmp);
            } catch (ParseException ex) {
                Logger.getLogger(Converter.class.getName()).log(Level.SEVERE, null, ex);
            }
            cal.setTime(epoch);
            Tuple tuple = holding.get(epoch);
            if (tuple == null) {
                tuple = new Tuple();
                holding.put(epoch, tuple);
            }
            queryTimeSlot.setParameter("docType", docType);
            queryTimeSlot.setParameter("date", epoch);
            try {
                ats = (TimeSlot)queryTimeSlot.getSingleResult();
                insertATS = false;
            } catch (Exception e) {
                insertATS = true;
                ats = new TimeSlot();
                atsk = new TimeSlotKey();
                atsk.setSlotDate(epoch);
                atsk.setDocType(docType);
                ats.setHour(cal.get(Calendar.HOUR_OF_DAY));
                ats.setSlotKey(atsk);
            }
            if (processMM) {
                queryDocument.setParameter("id", event.getUpdEventLogDocId());
                queryDocument.setParameter("doc", docType);

                try {
                    doc = (Document)queryDocument.getSingleResult();
                    insertDoc = false;
                } catch (Exception e) {
                    doc = new Document();
                    docKey = new DocumentKey();
                    docKey.setDocid(event.getUpdEventLogDocId());
                    docKey.setType(docType);
                    doc.setDocKey(docKey);
                    insertDoc = true;
                }
            }
            try {
                ats.getDocuments().add(doc);
            } catch (Exception e) {
                Logger.getLogger(Converter.class.getName()).log(Level.SEVERE, "{0}", e);
                System.exit(-1);
            }
            if (processMM) {
                doc.getTimes().add(ats);
            }

TimeSlot Entity

@Entity
@Table(name = "TimeSlot", catalog = "Analytics")

public class TimeSlot implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue
    @Basic(optional=false)
    @Column(name="id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "slotKey")
    private TimeSlotKey slotKey;

    @Basic(optional = false)
    @Column(name = "slotHour")
    private int slotHour;
    @Basic(optional = false)
    @Column(name = "inserts")
    private int inserts;
    @Basic(optional = false)
    @Column(name = "deletes")
    private int deletes;
    @Basic(optional = false)
    @Column(name = "active")
    private int active;
    @ManyToMany(fetch=FetchType.LAZY)
    @JoinColumn(name="doc_id")
    private Collection<Document> documents;
    @Basic(optional = false)
    @Version
    @Column(name = "version")
    private int version;


    public TimeSlot() {
        documents = new ArrayList<Document>(0);
    }

    public Collection<Document> getDocuments() {
            return documents;
    }

    public void setDocuments(Collection<Document>documents) {
            this.documents = documents;
    }

    public int getHour() {
        return slotHour;
    }

    public void setHour(int slotHour) {
        this.slotHour = slotHour;
    }

     @Override
    public int hashCode() {
        int hash = 0;
        hash += (slotKey != null ? slotKey.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof ActivityTimeSlot)) {
            return false;
        }

}

Документы следующие:

@Entity
@Table(name = "Documents", catalog = "Analytics")
public class Document implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue
    @Basic(optional=false)
    @Column(name="id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "docKey")
    private DocumentKey docKey;
    @Basic(optional = false)
    @Column(name = "inserts")
    private int inserts;
    @Basic(optional = false)
    @Column(name = "deletes")
    private int deletes;
    @ManyToMany(fetch=FetchType.LAZY, mappedBy="")
    @JoinColumn(name="slot_id")
    private Collection<TimeSlot> times;
    @Basic(optional = false)
    @Version
    @Column(name = "version")
    private int version;


    public Document() {
        times = new ArrayList<TimeSlot>(0);
        inserts = 0;
        deletes = 0;
    }

    @Override
    public int hashCode() {
        return docKey.hashCode();
    }

    @Override
    public boolean equals(Object object) {
        return docKey.equals(object);
    }

    public int getDeletes() {
        return deletes;
    }

    public void setDeletes(int deletes) {
        this.deletes = deletes;
    }

    public void incrDeletes() {
        deletes++;
    }

    public void incrInserts() {
        inserts++;
    }
    public int getInserts() {
        return inserts;
    }

    public void setInserts(int inserts) {
        this.inserts = inserts;
    }

    public Pair getPair() {
        return new Pair(inserts, deletes);
    }

    @Override
    public String toString() {
        return docKey.toString();
    }


    public Collection<ActivityTimeSlot> getTimes() {
            return times;
    }
    public void setTimes(Collection<ActivityTimeSlot>times) {
            this.times = times;
    }

    public DocumentKey getDocKey() {
        return docKey;
    }

    public void setDocKey(DocumentKey docKey) {
        this.docKey = docKey;
    }

    public Integer getId() {
        return id;
    }

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

}

Новая информация

Я через это случилось ManyToMany предлагает удалить запись в таблице присоединения

что практически идентично. Просто я не понимаю ответ Артура. Также я заметил, что в состоянии mysql innodb он выполняет внешнее левое соединение ... это действительно необходимо?

Итак, в EntityA у меня должен быть метод add (EntityB), а в EntityB у меня должен быть метод add (EntityA) в этих методах I

public void add(EntityB entity) {
    entity.getList().add(this);

    getList().add(entity);
}

Я не вижу, как это функционально отличается от того, что у меня есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...