質問

私は非常に特別なセットアップを持っています:私はJavaのすべてのクラスを作成し、アプリケーションでそれらを接続します(いくつかの多くの関係)。

次に、オブジェクトを繰り返してデータベースに保存したいと思います。時々、オブジェクトがすでにデータベース内にある場合、再度持続する必要はありません。

HashCode()とequals() - メソッドは正しいものを実装しましたが、それにもかかわらず、私のem.merge()はオブジェクトを挿入します。

また:

いくつかのオブジェクトを作成します。つまり、プレーヤーを作成し、どのチームであるかを設定します。チームはJavaの異なるオブジェクトである可能性がありますが、「等しい」 - メソッドによれば、それらは同じです。したがって、プレーヤーを保存する場合、チームはそれに応じて保存する必要があります(それは機能します)が、チームがデータベースに存在する場合(Equals-Methodに従って)、それは再度挿入されるべきではありませんが、関係を設定する必要があります。コース。

私が間違っていることは何ですか?より多くの情報が必要ですか?

    private static void saveModels(final Set<?> models) {
    EntityManagerFactory factory = null;

    factory = Persistence.createEntityManagerFactory("sqlite");

    EntityManager manager = factory.createEntityManager();

    manager.getTransaction().begin();

    for (Object object : models) {
        manager.merge(object);
    }

    manager.getTransaction().commit();

    manager.close();
    factory.close();
}

編集

@Entity
public class Team {

    private long id;
    private String description;

    @Id
    @GeneratedValue
    public long getId() {
        return id;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description= description;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + description.length();
        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Team other = (Team) obj;
        if (!description.equals(other.getDescription())) {
            return false;
        }
        return true;
    }
}


@Entity
public class Player {
    private long id;
    private Team team;
    private String name;

    @Id
    @GeneratedValue
    public long getId() {
        return id;
    }

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

    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, targetEntity = Team.class)
    @JoinColumn(name = "team_id")
    public Team getTeam() {
        return team;
    }

    public void setTeam(Team team) {
        this.team = team;
    }

    public String getName() {
        return name;
    }

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


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

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

        Player other = (Player) obj;
        return other.getName().equals(name);
    }
}
役に立ちましたか?

解決

JPAは@IDフィールドを使用してマージを行いますが、EqualsおよびHashCodeメソッドを使用して、データベースにエンティティが既に存在するかどうかを確認しません。

Bozhoが示唆するように、チームに@Onetomanyマッピングを追加しますが、このようにします。

@OneToMany(cascade = { CascadeType.ALL })
private List<Player> players = new ArrayList<Player>();

public void addPlayer(Player player) {
    player.setTeam(this);
    players.add(player);
}

public Collection<Player> getPlayers() {
    return new ArrayList<Player>(this.players);
}

あなたが一度にたくさんのエンティテを融合しているので、私はあなたがCSVまたは何かからかさばる輸入をしていると仮定しています。次に、CSVのすべてのラインに新しいチーム/プレーヤーを作成するのではなく、名前でキーを付けられたチームのマップを保持し、関連するチームにプレーヤーを追加します。

だから、ではなく

Team t = new Team();
t.setName(teamName)
Player p = new Player();
p.setName(playerName);
p.setTeam(t);

行う

Map<String, Team> teams = new HashMap<String,Team>();

...

if (!teams.containsKey(teamName)) {
    Team t = new Team();
    t.setDescription(teamName);
    teams.put(teamName, t)
}

Player p = new Player();
p.setName(p);
teams.get(teamName).addPlayer(p);

...

saveModels(teams.values());

他のヒント

チームのクラスAコレクションのフィールドとしてのコレクションを考慮して、関係を双方向にしてみてください。これはそのように注釈が付けられます

@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, targetEntity = Team.class)
Collection<Player> getPlayers() {
  return this.players;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top