1

我在挠头,想知道为什么每当我尝试使用 spring 和 hibernate 将新用户保存到我的数据库时,这个异常就会不断弹出。

我已经仔细检查并确保存在@Entity 注释,甚至添加了@Table 注释来说明该对象属于哪个表,但我仍然收到此错误

下面是我的用户对象:

    @Entity
@Table(name = "USER")
public class User implements Serializable {

    /**
     * Serial version
     */
    private static final long serialVersionUID = 1L;

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_BIO = "Bio";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String SURNAME = "Surname";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_FIRST_NAME = "FirstName";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_PASSWORD = "Password";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_EMAIL = "EmailAddress";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_USERNAME = "Username";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final String KEY_USER_ID = "UserId";

    @JsonElement(type = JsonElementType.JSON_KEY)
    public static final int USERNAME_LENGTH = 5;

    @Id
    @Column(name = "USER_ID")
    @NotNull
    private String id;

    @Column(name = "USERNAME", nullable = false, unique = true)
    @NotNull
    private String username;

    @Column(name = "EMAIL_ADDRESS", nullable = false, unique = true)
    @NotNull
    private String emailAddress;

    @Column(name = "PASSWORD")
    @NotNull
    @Size(min = 5, max = 25)
    private String password;

    @Column(name = "FIRST_NAME")
    private String firstName;

    @Column(name = "SURNAME")
    private String surname;

    @Column(name = "COUNTRY")
    private String country;

    @Column(name = "BIO")
    private String bio;



    @Column(name = "SESSION_ID")
    private String sessionId;

    @Column(name = "LAST_REST_CALL_MADE")
    private Date lastRestCallMade;

    @Column(name = "STATUS")
    @NotNull
    private int status;

    @OneToOne
    @JoinColumn(name = "imageId")
    private ProfileImage profileImage;

    public User() {
        id = UUID.randomUUID().toString();
    }

    @JsonElement(type = JsonElementType.GETTER)
    public ProfileImage getProfileImage() {
        return profileImage;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setProfileImage(ProfileImage profileImage) {
        this.profileImage = profileImage;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getId() {
        return id;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setId(String id) {
        this.id = id;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getUsername() {
        return username;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setUsername(String username) {
        this.username = username;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getEmailAddress() {
        return emailAddress;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getPassword() {
        return password;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setPassword(String password) {
        this.password = password;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getFirstName() {
        return firstName;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getSurname() {
        return surname;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setSurname(String surname) {
        this.surname = surname;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getBio() {
        return bio;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setBio(String bio) {
        this.bio = bio;
    }

    @JsonElement(type = JsonElementType.GETTER)
    public String getCountry() {
        return country;
    }

    @JsonElement(type = JsonElementType.SETTER)
    public void setCountry(String country) {
        this.country = country;
    }

    /**
     * @return the sessionId
     */
    public String getSessionId() {
        return sessionId;
    }

    /**
     * @param sessionId the sessionId to set
     */
    @JsonElement(type = JsonElementType.SETTER)
    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

    /**
     * @return the lastRestCallMade
     */
    public Date getLastRestCallMade() {
        return lastRestCallMade;
    }

    /**
     * @param lastRestCallMade the lastRestCallMade to set
     */
    public void setLastRestCallMade(Date lastRestCallMade) {
        this.lastRestCallMade = lastRestCallMade;
    }

    /**
     * @return the status
     */
    public int getStatus() {
        return status;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(int status) {
        this.status = status;
    }

}

这是我的 userDao 所做的

@Override
    public void addNewUser(User user) throws InvalidDataException {
        // TODO: Add Transaction manager object here either using annototation
        // or creating it programatically

        if (mSessionFactory != null) {
            session = mSessionFactory.getCurrentSession();
            session.beginTransaction();
            if (user.getUsername() == null
                    || user.getUsername().length() < User.USERNAME_LENGTH) {
                throw new InvalidDataException(
                        InvalidDataException.ERROR_USERNAME_NULL);
            }

            session.save(user);

        }else{
            throw new RuntimeException("mSession is null");
        }
    }

这里很简单。

完整的stracktrace如下:

org.hibernate.MappingException: Unknown entity: com.jr.freedom.user.User
    at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1092)
    at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1399)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:117)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
    at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:753)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:745)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:741)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
    at $Proxy20.save(Unknown Source)
    at com.jr.freedom.dao.UserDao.addNewUser(UserDao.java:50)
    at com.jr.freedom.user.UserService.registerNewUser(UserService.java:47)
    at com.jr.freedom.controllers.UserController.createNewAccount(UserController.java:57)
    at com.test.jr.freedom.controllers.UserControllerTest.testCreateNewAccount(UserControllerTest.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

当我调用 session.save(user) 时它崩溃了;

4

4 回答 4

2

答对了。这是我配置 sessionFactory 的 xml 配置文件中的问题:

<property name="annotatedClasses">
            <list>
                <value>com.jr.freedom.user.User</value>
                <value>com.jr.freedom.user.ProfileImage</value>
            </list>
        </property>

下面这个 bean 上没有:

<bean id="mySessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="configLocation" value="hibernate.cfg.xml" />
        <property name="annotatedClasses">
            <list>
                <value>com.jr.freedom.user.User</value>
                <value>com.jr.freedom.user.ProfileImage</value>
            </list>
        </property>

    </bean>

所以我添加了它并且它有效!问题是,如果我必须维护和使用 100 个实体怎么办。在这个 sessionFactory 中创建一长串 annotatedClasses 值将是一件苦差事!知道如何告诉 spring 或 hibernate 说“请扫描选定的包并找到并使用我的实体标记的对象”。

于 2013-03-20T16:33:11.190 回答
0

回答您在答案中发布的问题。
您可以使用实体管理器自动检测休眠实体。

class 元素指定您将映射的完全限定的类名。默认情况下,存档中找到的所有正确注释的类和所有 hbm.xml 文件都添加到持久性单元配置中。您可以通过类元素添加一些外部实体

. http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html

于 2013-03-20T16:59:34.277 回答
0

您可以告诉任何 JPA 提供者扫描一个 jar,但是您需要将所有实体类打包在一个单独的 jar 中。任何其他解决方案都是提供商特定的黑客。我通过使用 google 反射扫描注解,然后使用 Hibernate 的 EjbConfiguration 类注册所有实体注解类来做到这一点;但这在 Hibernate 4 中已被弃用,并将在 Hibernate 5 中消失。

于 2013-03-20T17:37:53.447 回答
0

我忘记将我的 hbm.xml 添加到我的 cfg.xml 文件中。我一添加它,这个异常就消失了。

<mapping resource="com/swipex/backend/hibernate/CServiceCenters.hbm.xml" />
于 2014-10-07T04:24:33.333 回答