составной первичный ключ не сопоставляется

#java #mysql #hibernate #jpa

#java #mysql #спящий режим #jpa

Вопрос:

Таблицы:

 CREATE TABLE `parent_table` (
  `parent_id` int NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`parent_id`),
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `child_table` (
  `child_id` int NOT NULL AUTO_INCREMENT,
  `parent_id` int NOT NULL,
  PRIMARY KEY (`child_id`,`parent_id`),
  FOREIGN KEY `fk2` (`parent_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  

Классы сущностей:

 @Setter
@Getter
@Entity
@Table(name = "parent_table")
public class Parent implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "parent_id")
    private int parentId;
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL,orphanRemoval = true)
    private List<Child> childs=new ArrayList<Child>();
    
    }


@Getter
@Setter
@EqualsAndHashCode
public class ChildPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    @Column(name="parent_id",nullable = false) 
    private int parentId;

    @Column(name="child_id")
    private int childId;
}



@Getter
@Setter
@EqualsAndHashCode
@Entity
@IdClass(ChildPK.class)

@Table(name = "child_table")
public class Child implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="child_id")
    private int childId;
     
      
    @Id
    @TableGenerator(name = "child_id_generator", table = "id_sequence", initialValue = 1, allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "child_id_generator")
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id",insertable = false,updatable = false)
    private Parent parent;
    
    }

class MainClass{
    
    public static void main(String[] args)
    {
    entityManager.persist(parent);//in child_table parent_id storing as 0
    }
    }
  

В столбце child_table parent_id в качестве внешнего ключа и части составного первичного ключа.

Внутри встроенного класса невозможно использовать генератор идентификаторов. поэтому я использую здесь классы идентификаторов. Для генерации значения автоматического увеличения для столбца child_id.

Я не могу сохранить значение parent_id, сгенерированное из родительской таблицы, в дочерней таблице в качестве значения внешнего ключа, которое оно хранит как 0.

может кто-нибудь, пожалуйста, проверьте сопоставления, помогите мне…..

заранее спасибо…

Ответ №1:

Если дочерний идентификатор уже уникален, зачем вам нужно, чтобы родительский идентификатор был частью первичного ключа? Просто используйте:

 @Setter
@Getter
@Entity
@Table(name = "parent_table")
public class Parent implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "parent_id")
    private int parentId;
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL,orphanRemoval = true)
    private List<Child> childs=new ArrayList<Child>();
    
    }


@Getter
@Setter
@EqualsAndHashCode
@Entity
@Table(name = "child_table")
public class Child implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="child_id")
    @TableGenerator(name = "child_id_generator", table = "id_sequence", initialValue = 1, allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "child_id_generator")
    private int childId;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private Parent parent;
    
    }
  

Комментарии:

1. согласно бизнес-правилу, он должен быть составным первичным ключом.

2. Спасибо @Christian Beikov.

Ответ №2:

 @Setter
@Getter
@Entity
@Table(name = "parent_table")
public class Parent implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "parent_id")
    private int parentId;
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL,orphanRemoval = true)
    private List<Child> childs=new ArrayList<Child>();
    
    }


@Getter
@Setter
@EqualsAndHashCode
@Embeddable
public class ChildPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    @Column(name="parent_id",nullable = false) 
    private int parentId;

        @TableGenerator(name = "child_id_generator", table = "id_sequence", initialValue = 1, allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "child_id_generator")
    @Column(name="child_id")
    private int childId;
}

@Getter
@Setter
@EqualsAndHashCode
@Entity
 @Table(name = "child_table")
    public class Child implements Serializable {
        private static final long serialVersionUID = 1L;

        @EmbeddableId
        private ChildPK childPk=new ChildPk(); 
   
        @ManyToOne(fetch = FetchType.LAZY)
        @MapsId("parentId")
        @JoinColumn(name = "parent_id",insertable = false,updatable = false)
        private Parent parent;
        
        }

class MainClass{
    
    public static void main(String[] args)
    {
    entityManager.persist(parent);//in child_table parent_id storing as 0
    }
    }