как решить мою проблему с базой данных?(MappingException) - PullRequest
0 голосов
/ 24 мая 2019

Я изучаю весеннюю загрузку 2 и спящий режим 5. На этот раз я использовал две таблицы и отношения один ко многим.Ошибка происходит здесь.

Я уже нашел несколько советов в stackoverflow, таких как изменение application.properties, создание средней таблицы с именем users_sites.Однако, это не решило мою проблему.

Это мои базы данных.

CREATE TABLE `sites` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(45) DEFAULT NULL,
  `siteURL` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `username_idx` (`username`),
  CONSTRAINT `username` FOREIGN KEY (`username`) REFERENCES `users` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `users` (
  `username` varchar(45) NOT NULL,
  `password` varchar(255) NOT NULL,
  PRIMARY KEY (`username`),
  UNIQUE KEY `id_UNIQUE` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Это мои модели calsses.

Entity
@Table(name = "users")
@EntityListeners(AuditingEntityListener.class)
public class User {
    private String username;
    private String password;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    @JoinColumn(name="username")
    private List<Site> sites = new ArrayList<Site>();

    public User() {

    }

    public User(String username, String password) {
        setUsername(username);
        setPassword(password);
    }

    @Id
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Column(name = "password", nullable = false)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<Site> getSites() {
        return sites;
    }

    public void setSites(List<Site> sites) {
        this.sites = sites;
    }

    public void addSite(Site site) {
        this.sites.add(site);
    }
}
@Entity
@Table(name = "sites")
@EntityListeners(AuditingEntityListener.class)
@IdClass(Site.class)
public class Site implements Serializable{
    private long id;
    private User user;
    private String siteURL;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }

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

    @ManyToOne
    @JoinColumn(name="username", referencedColumnName = "username", insertable = false, updatable = false) 
    public User getUser() {
        return user;
    }

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

    @Column(name = "siteURL", nullable = false)
    public String getSiteURL() {
        return siteURL;
    }

    public void setSiteURL(String siteName) {
        this.siteURL = siteName;
    }
}

Сообщение об ошибке здесь.

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44) ~[spring-boot-test-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) ~[junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) ~[junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) ~[junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) ~[junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) ~[junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) ~[junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) ~[junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209) ~[.cp/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: users, for columns: [org.hibernate.mapping.Column(sites)]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127) ~[spring-boot-test-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    ... 26 common frames omitted
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: users, for columns: [org.hibernate.mapping.Column(sites)]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:402) ~[spring-orm-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    ... 42 common frames omitted
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: users, for columns: [org.hibernate.mapping.Column(sites)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:486) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:453) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.mapping.Property.isValid(Property.java:226) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:624) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.mapping.RootClass.validate(RootClass.java:267) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:347) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:466) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    ... 46 common frames omitted

Как я могу решить эту проблему?Помоги мне.


Спасибо за ответы.Я решил свою проблему с проверенным ответом.Затем, однако, у меня появилась новая проблема, которая не сохраняла информацию о сайте у пользователя в базе данных.(Понятно, что я не могу загрузить информацию о сайте от пользователя.) (На самом деле это было спокойное исследование.)

Это мой тестовый код.

@Test
    public void test() {
        Site site1 = new Site();
        site1.setSiteURL("www.test.com");
        Site site2 = new Site();
        site2.setSiteURL("www.test1.com");

        restTemplate.postForEntity(getRootUrl()+ "/sites", site1, Site.class);
        restTemplate.postForEntity(getRootUrl()+ "/sites", site2, Site.class);

        User user1 = new User();
        user1.setUsername("1111");
        user1.setPassword("12131");

        user1.addSite(site1);
        user1.addSite(site2);

        User user2 = new User();
        user2.setUsername("2222");
        user2.setPassword("1241");

        user2.addSite(site1);

        restTemplate.postForEntity(getRootUrl()+ "/users", user1, User.class);
        restTemplate.postForEntity(getRootUrl()+ "/users", user2, User.class);

        User calledUser1 = restTemplate.getForObject(getRootUrl()+"/users/"+user1.getUsername(), User.class);
        System.out.println("Username: " + calledUser1.getUsername() + ", Password: " + calledUser1.getPassword());
        for (Site site : calledUser1.getSites()) {
            System.out.println("Sign up site: " + site.getSiteURL());
        }
        User calledUser2 = restTemplate.getForObject(getRootUrl()+"/users/"+user2.getUsername(), User.class);
        System.out.println("Username: " + calledUser2.getUsername() + ", Password: " + calledUser2.getPassword());
        for (Site site : calledUser2.getSites()) {
            System.out.println("Sign up site: " + site.getSiteURL());
        }
    }

В результате этого кода,SiteURL и пользовательская информация сохраняются хорошо.Но когда я загружаю информацию о пользователях из базы данных, информация о сайтах отсутствует.Вы можете мне помочь?

Ответы [ 3 ]

1 голос
/ 24 мая 2019
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: users, for columns: [org.hibernate.mapping.Column(sites)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:486) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:453) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]

Речь идет о настройке стратегии доступа.(т. е. доступ на основе полей или свойств).Какой из них использовать, зависит от размещения @Id из документов :

По умолчанию размещение аннотации @Id дает стратегию доступа по умолчанию.При размещении в поле Hibernate принимает полевой доступ.При размещении на получателе идентификатора Hibernate будет использовать доступ на основе свойств.

В User, поскольку его @Id размещен на получателе, будет использоваться доступ на основе свойств, и Hibernate проверитесли все получатели правильно настроены.(Если это доступ на основе полей, вместо этого он будет проверять наличие полей). Правильно сконфигурированное здесь означает, что для получения требуется выполнить любое из следующих условий:

  • Аннотировано некоторыми сопоставлениями, такими как @Column, @OneToMany и т. Д.
  • Если типом является базовый тип или @Entity, будет применяться настройка по умолчанию, даже если аннотации сопоставления не отмечены.
  • Аннотированныйс @Transient, если вы не хотите отображать его.

Но getSites() в User не удовлетворяет ни одному из вышеперечисленных условий и поэтому жалуется.Поэтому переместите @OneToMany из поля в получатель:

private List<Site> sites = new ArrayList<Site>();

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
public List<Site> getSites() {
        return sites;
}

Если вы хотите использовать полевой доступ только для сайта, но продолжаете использовать имущественный доступ для других, я думаю, вы можете использовать @Access( AccessType.FIELD ) переопределить для поля сайта:

@Access(AccessType.FIELD)
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Site> sites = new ArrayList<Site>();


@Transient
public List<Site> getSites() {
        return sites;
}
0 голосов
/ 24 мая 2019

Поместите файл applicationContext.xml в каталог src / main / resources.Он будет скопирован в каталог classpath, и вы сможете получить к нему доступ с помощью

@ ContextConfiguration ("/ applicationContext.xml")

Из Spring-Documentation : Простой путь, например context.xml, будет обрабатываться как ресурс classpath из того же пакета, в котором определен тестовый класс.Путь, начинающийся с косой черты, рассматривается как полностью определенное расположение пути к классу, например "/org/example/config.xml".

Поэтому важно добавить косую черту при обращении к файлу в корневом каталоге.пути к классам

0 голосов
/ 24 мая 2019

Удалите @JoinColumn(name="username") из private List<Site> sites = new ArrayList<Site>();

В двунаправленном отношении @OneToMany @ManyToOne, только один объект может быть владельцем.

проверить это сообщение для более.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...