强制执行刷新以获取存储EmbeddedId的新主键ID

时间:2017-06-06 07:27:58

标签: java entity-framework hibernate jpa eclipselink

我们正在使用EmbeddedId,我们在其中一个Entity中使用了Role: +-----------------------------+ | roleId | name | discription | +-----------------------------+ Rights: +-----------------------------+ | rightId | name | discription| +-----------------------------+ rightrole +--------------------------------------+ | roleId | rightId | some other column | +--------------------------------------+

表格如下:

@Entity
@Table(name = "role")
public class Role {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @NotNull
    @Column(nullable = false)
    private Long roleID;


    @OneToMany(cascade = CascadeType.ALL, mappedBy = "role", fetch = FetchType.LAZY)
    private List<RightRole> rightRoleList;

.......
}

角色表的实体是:

    @Entity
    @Table(name = "rightrole")
    public class RightRole extends BaseEntity<RightRolePK> {

        private static final long serialVersionUID = 1L;

        @EmbeddedId
        protected RightRolePK rightRolePK;


        @JoinColumn(name = "roleID", referencedColumnName = "roleID", insertable = false, updatable = false)
        @ManyToOne(fetch = FetchType.LAZY)
        private Role role;

        @JoinColumn(name = "rightID", referencedColumnName = "rightID", insertable = false, updatable = false)
        @ManyToOne(fetch = FetchType.LAZY)
        private Right right;

        ......
     }


    @Embeddable
    public class RightRolePK implements Serializable {
    private static final long serialVersionUID = 1L;

      @Basic(optional = false)
      @NotNull
      @Column(nullable = false)
      private long roleID;

      @Basic(optional = false)
      @NotNull
      @Column(nullable = false)
     private long rightID;

   .....

}

rightrole表的实体是:

role

我的问题是每当我想用rights创建新的store(persist)时,首先我需要role flush个对象然后我必须id为角色获取新生成的rightrole。然后我可以把它放在rightrole实体的对象中。

有什么方法可以在角色对象中设置Auto Generated列表并一次性保留它。

这种冲洗套管是我们的性能瓶颈,因为对于批量插入,我们必须坚持单个单个物体。

我们正在使用 - (IBAction)selectBtn:(id)sender { ParcelPickUpViewController *vc = [[HomeScreenVC alloc]initWithNibName:@"pickUpVC" bundle:nil]; [self.viewController pushViewController:vc animated: YES]; [self.viewController setNavigationBarHidden:YES animated:YES]; } 主键。

2 个答案:

答案 0 :(得分:2)

JPA 2.0允许派生ID,通过添加@MapsId进行扩展以更好地支持这一点。保持其他一切但使用:

public static class MapForEquityCalculator extends Mapper<LongWritable, Text, Text, IntWritable> {
    public int GetIndex(int R1, int R2, boolean IsSuited) {
        if (IsSuited) {
            return (int)(((13 - Math.ceil((double)Math.max(R1, R2) / 4)) * 13) + (13 - Math.ceil((double)Math.min(R1, R2) / 4)));
        } else {
            return (int)(((13 - Math.ceil((double)Math.min(R1, R2) / 4)) * 13) + (13 - Math.ceil((double)Math.max(R1, R2) / 4)));
        }
    }

    public void map(LongWritable key, Text value, Context con) throws IOException, InterruptedException {
            String line = value.toString();
            String[] cards=line.split(",");
            int ind_1 = GetIndex(Integer.parseInt(cards[0]),Integer.parseInt(cards[1]),Integer.parseInt(cards[0])%4 == Integer.parseInt(cards[1])%4);
            int ind_2 = GetIndex(Integer.parseInt(cards[2]),Integer.parseInt(cards[3]),Integer.parseInt(cards[2])%4 == Integer.parseInt(cards[3])%4);
            int ind_3 = GetIndex(Integer.parseInt(cards[4]),Integer.parseInt(cards[5]),Integer.parseInt(cards[4])%4 == Integer.parseInt(cards[4])%4);

            Text outputKey = new Text(Integer.toString(ind_1) +"," + Integer.toString(ind_2) +"," + Integer.toString(ind_3));
            Text outputValue = new Text(line);
            con.write(outputKey, outputValue);
    }

}

public static class ReduceForEquityCalculator extends Reducer<Text, IntWritable, Text, IntWritable> {

    public static final int HandRankSize = 32487834;
    public static int HR[] = new int[HandRankSize];

    protected static final int littleEndianByteArrayToInt(byte[] b, int offset) {
    return (b[offset + 3] << 24) + ((b[offset + 2] & 0xFF) << 16)
            + ((b[offset + 1] & 0xFF) << 8) + (b[offset] & 0xFF);
    }



    public void setup(Context context) throws IOException{
        Path pt=new Path("gs://mybucket/HandRanks.dat");
        Configuration conf = new Configuration();
        FileSystem fs = pt.getFileSystem(conf);
        int tableSize = HandRankSize*4;
        byte[] b = new byte[tableSize];
        try {
            FileInputStream fr = new FileInputStream(fs.open(pt));
            int bytesRead = fr.read(b, 0, tableSize);
            if (bytesRead != tableSize) {
            }
            fr.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
        for (int i = 0; i < HandRankSize; i++) {
            HR[i] = littleEndianByteArrayToInt(b, i * 4);
        }
    }

    public void reduce(Text word, Text value, Context con) throws IOException, InterruptedException {
        String line = value.toString();
        String[] cards_string=line.split(",");
        Integer[] cards = new Integer[cards_string.length];
        int i=0;
        for(String str:cards_string){
            cards[i]=Integer.parseInt(str);//Exception in this line
            i++;
        }


        int c0, c1, c2, c3, c4, c5, c6;

        int u0, u1, u2, u3, u4, u5;
        int su0, su1, su2, su3, su4, su5;
        int tu0, tu1, tu2, tu3, tu4, tu5;

        u0 = HR[53+cards[0]];
        u1 = HR[u0+cards[1]];
        su0 = HR[53+cards[2]];
        su1 = HR[su0+cards[3]];
        tu0 = HR[53+cards[4]];
        tu1 = HR[su0+cards[5]];

        int A_B_C = 0;
        int A_C_B = 0;
        int A_BC = 0;
        int AB_C = 0;
        int AC_B = 0;
        int ABC = 0;
        int B_A_C = 0;
        int B_C_A = 0;
        int B_AC = 0;
        int BC_A = 0;
        int C_A_B = 0;
        int C_B_A = 0;
        int C_AB = 0;

        for (int com1 = 1; com1 < 49; com1++) {
            if (com1 != cards[0] && com1 != cards[1] && com1 != cards[2] && com1 != cards[3] && com1 != cards[4] && com1 != cards[5]) {
                u2 = HR[u1+com1];
                su2 = HR[su1+com1];
                tu2 = HR[tu1+com1];
                for (int com2 = com1 + 1; com2 < 50; com2++) {
                    if (com2 != cards[0] && com2 != cards[1] && com2 != cards[2] && com2 != cards[3] && com2 != cards[4] && com2 != cards[5]) {
                        u3 = HR[u2+com2];
                        su3 = HR[su2+com2];
                        tu3 = HR[tu2+com2];
                        for (int com3 = com2 + 1; com3 < 51; com3++) {
                            if (com3 != cards[0] && com3 != cards[1] && com3 != cards[2] && com3 != cards[3] && com3 != cards[4] && com3 != cards[5]) {
                                u4 = HR[u3+com3];
                                su4 = HR[su3+com3];
                                tu4 = HR[tu3+com3];
                                for (int com4 = com3 + 1; com4 < 52; com4++) {
                                    if (com4 != cards[0] && com4 != cards[1] && com4 != cards[2] && com4 != cards[3] && com4 != cards[4] && com4 != cards[5]) {
                                        u5 = HR[u4+com4];
                                        su5 = HR[su4+com4];
                                        tu5 = HR[tu4+com4];
                                        for (int com5 = com4 + 1; com5 < 53; com5++) {
                                            if (com5 != cards[0] && com5 != cards[1] && com5 != cards[2] && com5 != cards[3] && com5 != cards[4] && com5 != cards[5]) {
                                                int rank_a = HR[u5 + com5];
                                                int rank_b = HR[su5 + com5];
                                                int rank_c = HR[tu5 + com5];
                                                if (rank_a > rank_b && rank_b > rank_c) {
                                                    A_B_C++;
                                                } else if (rank_a > rank_c && rank_c > rank_b) {
                                                    A_C_B++;
                                                } else if (rank_a > rank_b && rank_b == rank_c) {
                                                    A_BC++;
                                                } else if (rank_a == rank_b && rank_b > rank_c) {
                                                    AB_C++;
                                                } else if (rank_a == rank_c && rank_c > rank_b) {
                                                    AC_B++;
                                                } else if (rank_a == rank_c && rank_a == rank_b) {
                                                    ABC++;  
                                                } else if (rank_b > rank_a && rank_a > rank_c) {
                                                    B_A_C++;
                                                } else if (rank_b > rank_c && rank_c > rank_a) {
                                                    B_C_A++;
                                                } else if (rank_b > rank_a && rank_a == rank_c) {
                                                    B_AC++;
                                                } else if (rank_b == rank_c && rank_c > rank_a) {
                                                    BC_A++;
                                                } else if (rank_c > rank_a && rank_a > rank_b) {
                                                    C_A_B++;
                                                } else if (rank_c > rank_b && rank_b > rank_a) {
                                                    C_B_A++;
                                                } else {
                                                    C_AB++;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        Text outputValue = new Text(Integer.toString(A_B_C) +"," + Integer.toString(A_C_B) + "," + Integer.toString(A_BC)+"," + Integer.toString(A_BC) +","+ Integer.toString(AB_C)+","+ Integer.toString(AC_B) +","+ Integer.toString(ABC)+"," +Integer.toString(B_A_C) +","+Integer.toString(B_C_A)+","+Integer.toString(B_AC) +","+Integer.toString(BC_A)+","+Integer.toString(C_A_B) +","+Integer.toString(C_B_A)+","+Integer.toString(C_AB) + "\n");
        con.write(word, outputValue);
    }
}

这将告诉JPA PK类中的@Entity @Table(name = "rightrole") public class RightRole extends BaseEntity<RightRolePK> { private static final long serialVersionUID = 1L; @EmbeddedId protected RightRolePK rightRolePK; @MapsId("roleID") @JoinColumn(name = "roleID", referencedColumnName = "roleID") @ManyToOne(fetch = FetchType.LAZY) private Role role; @MapsId("rightID") @JoinColumn(name = "rightID", referencedColumnName = "rightID", insertable = false, updatable = false) @ManyToOne(fetch = FetchType.LAZY) private Right right; ...... } roleID属性中的值由关系映射控制,并且在使用主键值同步到数据库之后将设置它来自参考。您只需要确保在调用persist之前设置关系,否则它没有主键。

即使引用的对象也是复合对象,这也有效。需要引用RightRole的东西会使用RightRolePK而不是Long值:

rightID

JPA还允许使用@Entity @Table(name = "wrong_right_role") public class WrongRightRole{ @EmbeddedId WrongRightRoleId wrongRightRoleId; @MapsId("rightRoleID") @JoinColumns({ @JoinColumn(name = "roleID", referencedColumnName = "roleID"), @JoinColumn(name = "rightID", referencedColumnName = "rightID") }) RightRole rightRole; } @Embeddable public class WrongRightRolePK implements Serializable { private static final long serialVersionUID = 1L; private RightRoleID rightRoleID; ..... } 注释标记rightrole映射,允许您从对象中删除@ID,并将其用作主要内容关键类而不是。

答案 1 :(得分:1)

使用@ManyToMany注释,您可以像这样定义您的实体:

作用:

 @Entity
    @Table(name = "role")
    public class Role {

        private static final long serialVersionUID = 1L;

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Basic(optional = false)
        @NotNull
        @Column(name = "ROLE_ID", nullable = false)
        private Long roleID;

        @JoinTable(name = "rightrole",
                joinColumns = {
                    @JoinColumn(name = "roleID", referencedColumnName = "ROLE_ID")},
                inverseJoinColumns = {
                    @JoinColumn(name = "rightID", referencedColumnName = "RIGHT_ID")})
        @ManyToMany
        private List<Right> rightList;

    }

您必须在@ManyToMany(cascade = {CascadeType.PERSIST})中写下inverseJoinColumns,否则如果删除子项,您的父数据将被删除。

右:

@Entity
@Table(name = "right")
public class Right {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @NotNull
    @Column(name = "RIGHT_ID",nullable = false)
    private Long rightId;

}

你可以简单地说:

    Role role = new  Role();
    List<Right> rightList = new ArrayList<>();
    Right right1 = new Right();
    Right right2 = new Right();
    rightList.add(right1);
    rightList.add(right2);
    role.setRightList(rightList);

并坚持

@poinTable注释即使没有实体也会在rightrole表中插入(只要该表只有role和id的id列),这样你就可以在db中得到这样的东西了

角色:

id name     etc
1  roleName etc

右:

id name       etc
1  rightName1 etc
2  rightName2 etc

rightrole:

roleId rightID
1      1
1      2