【发布时间】:2016-08-28 11:04:13
【问题描述】:
有两个实体:父级和子级。
@Entity
@Table(name = "university_group")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
private String name;
@OneToMany(mappedBy = "group", fetch = FetchType.LAZY, cascade = CascadeType.ALL,
orphanRemoval = true)
private Set<Student> students = new HashSet<>();
// getters, setters, constructor, equals+hashcode ...
}
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
private String name;
private String password;
private String email;
@ManyToOne(optional = false)
private Group group;
// getters, setters, constructor, equals+hashcode ...
}
通过em.remove(group) 删除组后抛出异常:
javax.persistence.PersistenceException:
org.hibernate.exception.ConstraintViolationException ...
org.hibernate.engine.jdbc.spi.SqlExceptionHelper: ERROR:
UPDATE or DELETE in table "university_group" breaks foreign key constraint "fk_20su8ubuwt33je1a3ygal7wd6" of table "student"
似乎 hibernate 并没有通过 Persistence Provider 删除组之前的学生,尽管它应该这样做。当然,我可以启用 DB 级联,但我会更好地解决问题。 有任何想法吗?
通过 Spring configs 配置 EntityManager
@Configuration
@EnableTransactionManagement
@PropertySource({"classpath:db.properties"})
public class PersistenceContext {
private static final String BASE_MODEL_SCAN_PACKAGE = "com.chiefhelpsystem.model";
@Value("${db.driverClassName}")
private String dbClassName;
@Value("${db.url}")
private String dbUrl;
@Value("${db.username}")
private String dbUserName;
@Value("${db.password}")
private String dbPassword;
@Bean
DataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setMaxIdle(20);
ds.setMinIdle(0);
ds.setMaxActive(20);
ds.setDriverClassName(dbClassName);
ds.setUrl(dbUrl);
ds.setUsername(dbUserName);
ds.setPassword(dbPassword);
return ds;
}
@Bean
PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
@Bean(destroyMethod = "destroy")
LocalContainerEntityManagerFactoryBean emf() {
LocalContainerEntityManagerFactoryBean emFactory =
new LocalContainerEntityManagerFactoryBean();
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setDatabase(Database.POSTGRESQL);
jpaVendorAdapter.setGenerateDdl(true);
jpaVendorAdapter.setShowSql(true);
emFactory.setDataSource(dataSource());
emFactory.setPackagesToScan(BASE_MODEL_SCAN_PACKAGE);
emFactory.setJpaVendorAdapter(jpaVendorAdapter);
emFactory.setJpaProperties(jpaProps());
emFactory.setPersistenceProvider(new HibernatePersistenceProvider());
return emFactory;
}
private Properties jpaProps() {
Properties properties = new Properties();
properties.setProperty("format_sql", "true");
return properties;
}
}
休眠 4.3.11、春季 4.3.2
【问题讨论】:
-
显示删除代码。
-
em.delete(entity);