Будьте в спящем режиме непосредственная связь объекта с общим PK между 3 классами

Сравнительный тест, данный GHad, измеряет много другого материала (такого как отражение, инстанцируя объектов, и т.д.) помимо получения длины. Если мы пытаемся избавиться от этих вещей тогда для одного вызова, я добираюсь следующие разы в микросекундах:

   file sum___19.0, per Iteration___19.0
    raf sum___16.0, per Iteration___16.0
channel sum__273.0, per Iteration__273.0

Для 100 выполнений и 10 000 повторений я добираюсь:

   file sum__1767629.0, per Iteration__1.7676290000000001
    raf sum___881284.0, per Iteration__0.8812840000000001
channel sum___414286.0, per Iteration__0.414286

я действительно выполнял следующий измененный код, дающий как аргумент название файла 100 МБ.

import java.io.*;
import java.nio.channels.*;
import java.net.*;
import java.util.*;

public class FileSizeBench {

  private static File file;
  private static FileChannel channel;
  private static RandomAccessFile raf;

  public static void main(String[] args) throws Exception {
    int runs = 1;
    int iterations = 1;

    file = new File(args[0]);
    channel = new FileInputStream(args[0]).getChannel();
    raf = new RandomAccessFile(args[0], "r");

    HashMap<String, Double> times = new HashMap<String, Double>();
    times.put("file", 0.0);
    times.put("channel", 0.0);
    times.put("raf", 0.0);

    long start;
    for (int i = 0; i < runs; ++i) {
      long l = file.length();

      start = System.nanoTime();
      for (int j = 0; j < iterations; ++j)
        if (l != file.length()) throw new Exception();
      times.put("file", times.get("file") + System.nanoTime() - start);

      start = System.nanoTime();
      for (int j = 0; j < iterations; ++j)
        if (l != channel.size()) throw new Exception();
      times.put("channel", times.get("channel") + System.nanoTime() - start);

      start = System.nanoTime();
      for (int j = 0; j < iterations; ++j)
        if (l != raf.length()) throw new Exception();
      times.put("raf", times.get("raf") + System.nanoTime() - start);
    }
    for (Map.Entry<String, Double> entry : times.entrySet()) {
        System.out.println(
            entry.getKey() + " sum: " + 1e-3 * entry.getValue() +
            ", per Iteration: " + (1e-3 * entry.getValue() / runs / iterations));
    }
  }
}
6
задан Community 23 May 2017 в 12:15
поделиться

2 ответа

Ненавижу говорить вам это, но у вас здесь двусторонние отношения. Человек ссылается на Сердце и Печень, и каждый из них имеет обратную ссылку на Человека. Аннотации, которые вы настроили для свойств Id ваших Heart и Liver, конкретно говорят о том, что они получают значение своего свойства Id, делегируя его свойству Person. В показанных вами примерах, которые не работают, вы еще не установили свойство Person для этих парней, и поэтому они, очевидно, не могут получить значение своего идентификатора.

Вы можете установить это отношение как истинное. однонаправленный OneToOne, который задокументирован в документации аннотаций Hibernate:

@Entity
public class Body {
    @Id
    public Long getId() { return id; }

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    public Heart getHeart() {
        return heart;
    }
    ...
}


@Entity
public class Heart {
    @Id
    public Long getId() { ...}
}

, или вы можете немного изменить наши объекты сущностей, чтобы упростить подключение обеих сторон отношения, например:

@Entity
public class Person {
   public long personId;
   private String name;
   public Heart heart;
   public Liver liver;
   // other fields

   @Id
   @GeneratedValue
   public long getPersonId() {return personId;}

   @OneToOne(cascade = CascadeType.ALL)
   @PrimaryKeyJoinColumn
   public Heart getHeart() {return heart;}

   public void setHeart(Heart heart){
      this.heart = heart;
      this.heart.setPerson(this);
   }

   @OneToOne(cascade = CascadeType.ALL)
   @PrimaryKeyJoinColumn
   public Liver getLiver() {return liver;}

   public void setLiver(Liver liver){
      this.liver = liver;
      this.liver.setPerson(this);
   }
   // other getters and setters and constructors
}
7
ответ дан 16 December 2019 в 21:41
поделиться

Я не пробовал, но могу сказать, что ....

Разница между обеими сторонами в том, что у класса Person нет mappedBy в его отображении.

Итак, для каждого One-To-One, Person имеет эталонное значение, которое Hibernate считает официальным. Напротив, для других объектов mappedBy указывает Hibernate не использовать значение, а перейти к этому объекту и рассмотреть сопоставленное свойство этого объекта.


Чтобы проверить, я правильно, вы можете установить только те значения, которые не имеют mappedBy , и сохранить объект Person (потому что это тот, который имеет каскады), и посмотреть, верен ли результат. .; -)

1
ответ дан 16 December 2019 в 21:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: