2017-03-07 4 views
4

Laut dem Buch, wenn ich eine ElementCOllection Liste aktualisiere, mache ich nicht die Transection.begin, der Hibernate wird automatisch committen, aber ich habe einen Test gemacht, das Ergebnis hat etwas falschHibernate hat die @ElementCollection nicht automatisch aktualisiert.

Mein Main.java ist

public class Main { 

private static UserService userService; 

private static Logger logger = LoggerFactory.getLogger(Main.class); 


public static void main(String[] args) { 
    ApplicationContext applicationContext = 
      new AnnotationConfigApplicationContext(RootConfig.class); 
    userService = applicationContext.getBean(UserService.class); 


    User user = new User("qwerty"); 
    user.getMessages().add("hello,world"); 
    userService.save(user); 
    User user1 = userService.findByName("qwerty"); 
    user1.getMessages().add("ncjdksckds"); 
    System.out.println(user); 
} 

}

und meine Konfiguration ist hier, Codierung nach dem Buch

@Configuration 
@ComponentScan(basePackages = {"org.zhy"}) 
@EnableJpaRepositories(basePackages = {"org.zhy.repository"}) 
@EnableTransactionManagement 
public class RootConfig { 
    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) { 
    LocalContainerEntityManagerFactoryBean emfb = 
      new LocalContainerEntityManagerFactoryBean(); 
    emfb.setDataSource(dataSource); 
    emfb.setJpaVendorAdapter(jpaVendorAdapter); 
    emfb.setPersistenceUnitName("demo"); 
    Properties hibernateProperties = new Properties(); 
    hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "create-drop"); 
    emfb.setJpaProperties(hibernateProperties); 

    emfb.setPackagesToScan("org.zhy.domain"); 
    return emfb; 
} 

@Bean 
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { 
    JpaTransactionManager transactionManager = new JpaTransactionManager(); 
    transactionManager.setEntityManagerFactory(entityManagerFactory); 
    return transactionManager; 
} 

@Bean 
public DataSource dataSource() { 
    DriverManagerDataSource ds = new DriverManagerDataSource(); 
    ds.setDriverClassName("com.mysql.jdbc.Driver"); 
    // some setting here such as url... 
    return ds; 
} 
@Bean 
public JpaVendorAdapter jpaVendorAdapter() { 
    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); 
    adapter.setGenerateDdl(false); 
    adapter.setDatabase(Database.MYSQL); 
    adapter.setShowSql(true); 
     adapter.setDatabasePlatform("org.hibernate.dialect.MySQLDialect"); 
    return adapter; 
} 

}

die Entity ist hier

@Entity 
public class User { 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long id; 
private String name; 
@ElementCollection(fetch = FetchType.EAGER) 
private List<String> messages = new ArrayList<String>(); 
//getter and setter 

wenn i user1.getMessages().add("ncjdksckds");
die Datenbank verwendet haben, die neue Nachricht in sie nicht automatisch spülen, ich will wissen, warum ????

+0

Sie haben keine Transaktionen in Ihrer Hauptmethode ausgeführt. Ich vermute, dass Ihre 'UserService'-Methoden transaktional sind. In diesem Fall funktioniert das 'userService.save', aber was auch immer Sie außerhalb der Methode tun, wird nicht in der Datenbank gespeichert. Wird hilfreich sein, wenn Sie den Code Ihrer Service-Methode posten. –

+0

ich löste es ... danke! ~~ – lovezhy

Antwort

0

Nicht sicher, auf welches Buch Sie sich beziehen, aber der Schlüssel zu @ElementCollection in Ihrem Fall ist, dass alle Operationen standardmäßig kaskadiert sind.

Angenommen, Ihr Dienst verfügt über alle öffentlichen Methoden, die als transaktional gekennzeichnet sind. Nach der Abfrage für den Benutzer handelt es sich um eine getrennte Entität, da es sich ab jetzt außerhalb eines Transaktionsbereichs befindet.

In Ihrem Code:

User user = new User("qwerty"); 
user.getMessages().add("hello,world"); 
userService.save(user); // new transaction start and finish 
User user1 = userService.findByName("qwerty"); // new transaction start and finish 
user1.getMessages().add("ncjdksckds"); // this change is outside of a transaction 

, um diese Änderung vorzunehmen persistend Sie merge die user1 Einheit wieder in den Persistenzkontext brauchen würde:

userService.merge(user1); 

Innerhalb Sie nennen würde:

entityManager.merge(user); 
Verwandte Themen