使用技術
・SpringBoot(Javaフレームワーク)
・JPA(ORマッパー)
・MySQL(DB)
やりたいこと
・単一トランザクション内で、単一テーブル(=テーブルAとする)に複数行を登録する
・テーブルAの主キーは自動連番(auto increment)
エラー
javax.persistence.EntityExistsException:
A different object with the same identifier value was already associated with the session : [モデル名]
org.springframework.dao.DataIntegrityViolationException: A different object with the same identifier value was already associated with the session :
要約すると、「主キーが重複してまっせ」ということですね。
複数レコードを一気に登録しようとしたとき、同じ主キーを自動連番してしまうことにより発生しているようです。
ソース(改善前、エラーが出る)
改善箇所は後ほど記載します。
Entity.Java
@Entity //エンティティクラスのアノテーション
@Getter //Getterの自動生成のアノテーション
@Setter //Setterの自動生成のアノテーション
@Table(name = "Entity") //テーブル名の指定
public class Entity {
@Id //idであることをアノテーションで明示する
@Column(name = "entity_id") //DB上のカラム名を指定する
private int id;
@Column(name = "detail")
private String detail;
}
EntityRepository.Java
@Repository
public interface EntityRepository extends JpaRepository<Entity, Long> {
}
EntityService.Java
@Autowired
private TransactionRepository transactionRepository;
@Transactional
public void someMethod() {
//Entityテーブルに複数のレコードを追加
List<Entity> entitys = new ArrayList<Entity>();
Entity entity1 = new Entity();
entity1.setDetail("適当な文字列-1");
entitys.add(entity1);
Entity entity2 = new Entity();
entity2.setDetail("適当な文字列-2");
entitys.add(entity2);
entityRepository.saveAll(entitys);
}
ソース(改善後)
モデルクラスの主キーに下記を追加します。
@GeneratedValue(strategy = GenerationType.IDENTITY)
クラス全体ではこうなります。
Entity.Java
@Entity //エンティティクラスのアノテーション
@Getter //Getterの自動生成のアノテーション
@Setter //Setterの自動生成のアノテーション
@Table(name = "Entity") //テーブル名の指定
public class Entity {
@Id //idであることをアノテーションで明示する
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "entity_id") //DB上のカラム名を指定する
private int id;
@Column(name = "detail")
private String detail;
}