合并时,多个OneToMany关系会导致不必要的选择语句

时间:2018-10-20 16:46:46

标签: java spring hibernate jpa spring-data-jpa

我有一个包含两个与两个不同实体不同的OneToMany关系的实体。如果我合并父实体,则会选择第二个关系中的每个条目。为什么?这不适用于第一个OneToMany关系。顺便说一句。如果我只有一个OneToMany关系,则不会出现该问题


测试案例:

https://hastebin.com/puzipezaci.java

@EnableAsync
@SpringBootApplication
public class TestsApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(TestsApplication.class, args);
    }

    @Autowired
    private UserService userService;

    @Override
    public void run(String... args) throws Exception {
        User user = this.userService.getUser("2018").get();

        for (int i = 0; i < 10; i++) {
            Book book = new Book();
            book.setUser(user);
            book.setTitle("TheBook->" + Math.random());
            book.setAuthor("TheAuthor");
            user.getBooks().add(book);

            InfoSheet infoSheet = new InfoSheet();
            infoSheet.setUser(user);
            infoSheet.setTitle("Sheet->" + Math.random());
            infoSheet.setType("Type->" + Math.random());
            user.getInfoSheets().add(infoSheet);
        }

        this.userService.save(user);
    }
}

这是我的sql输出:

我担心第16至36行 https://hastebin.com/teginasoya.sql

Hibernate: select books0_.playerUuid as playerUu4_0_0_, books0_.id as id1_0_0_, books0_.id as id1_0_1_, books0_.author as author2_0_1_, books0_.title as title3_0_1_, books0_.playerUuid as playerUu4_0_1_ from books books0_ where books0_.playerUuid=?
Hibernate: select user0_.playerUuid as playerUu1_2_0_ from users user0_ where user0_.playerUuid=?
Hibernate: select infosheets0_.playerUuid as playerUu4_1_0_, infosheets0_.id as id1_1_0_, infosheets0_.id as id1_1_1_, infosheets0_.title as title2_1_1_, infosheets0_.type as type3_1_1_, infosheets0_.playerUuid as playerUu4_1_1_ from infoSheets infosheets0_ where infosheets0_.playerUuid=?
Hibernate: select user0_.playerUuid as playerUu1_2_0_ from users user0_ where user0_.playerUuid=?
Hibernate: select user0_.playerUuid as playerUu1_2_1_, books1_.playerUuid as playerUu4_0_3_, books1_.id as id1_0_3_, books1_.id as id1_0_0_, books1_.author as author2_0_0_, books1_.title as title3_0_0_, books1_.playerUuid as playerUu4_0_0_ from users user0_ left outer join books books1_ on user0_.playerUuid=books1_.playerUuid where user0_.playerUuid=?
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into books (author, title, playerUuid) values (?, ?, ?)
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: insert into infoSheets (title, type, playerUuid) values (?, ?, ?)
Hibernate: select infosheet0_.id as id1_1_0_, infosheet0_.title as title2_1_0_, infosheet0_.type as type3_1_0_, infosheet0_.playerUuid as playerUu4_1_0_ from infoSheets infosheet0_ where infosheet0_.id=?
Hibernate: select infosheets0_.playerUuid as playerUu4_1_0_, infosheets0_.id as id1_1_0_, infosheets0_.id as id1_1_1_, infosheets0_.title as title2_1_1_, infosheets0_.type as type3_1_1_, infosheets0_.playerUuid as playerUu4_1_1_ from infoSheets infosheets0_ where infosheets0_.playerUuid=?

这是我的jpa-config:

https://hastebin.com/tivekuwado.java

@Configuration
public class JpaConfig {
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/testDb");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(true);
        vendorAdapter.setDatabase(Database.MYSQL);
        vendorAdapter.setGenerateDdl(true);

        LocalContainerEntityManagerFactoryBean emFactory = new LocalContainerEntityManagerFactoryBean();
        emFactory.setDataSource(dataSource());
        emFactory.setPackagesToScan("dev.project.tests.domain");
        emFactory.setJpaVendorAdapter(vendorAdapter);
        emFactory.setJpaProperties(properties());
        return emFactory;
    }

    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory 
 pEntityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(pEntityManagerFactory);

        return transactionManager;
    }

    private Properties properties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "update");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        properties.setProperty("hibernate.current_session_context_class", "thread");
        properties.setProperty("hibernate.enable_lazy_load_no_trans", "true");
        return properties;
    }
}

这是我的域模型:

@Entity
@Table(name = "users")
@DynamicUpdate
public class User {
    @Id
    private String playerUuid;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
    private Set<Book> books = new HashSet<>();

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
    private Set<InfoSheet> infoSheets = new HashSet<>();

第一个孩子实体:

https://hastebin.com/doxozoxaji.java

@Entity
@Table(name = "books")
public class Book {
    @ManyToOne
    @JoinColumn(name = "playerUuid")
    private User user;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String title = "";

    private String author = "";

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public int getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

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

        Book book = (Book) obj;
        return book.getTitle().equalsIgnoreCase(this.getTitle()) && book.getAuthor().equalsIgnoreCase(this.getAuthor());
    }

    @Override
    public int hashCode() {
        return Objects.hash(this.author, this.title);
    }
}

第二个儿童实体:

https://hastebin.com/xahapinama.java

@Entity
@Table(name = "infoSheets")
public class InfoSheet {
    @ManyToOne
    @JoinColumn(name = "playerUuid")
    private User user;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String title = "";
    private String type = "";

    public int getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
         this.type = type;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

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

        InfoSheet infoSheet = (InfoSheet) obj;
        return infoSheet.getTitle().equalsIgnoreCase(this.getTitle()) && infoSheet.getType().equalsIgnoreCase(this.getType());
    }

    @Override
    public int hashCode() {
        return Objects.hash(this.type, this.title);
    }
}

0 个答案:

没有答案