@ManyToOne ConstraintViolationException

Diskutiere @ManyToOne ConstraintViolationException im Data Tier Forum; Ich würde gerne in meinen Blog Posts speichern können. Dazu habe ich folgende Entities. Meinen Blog: @Entity @Table(name = "Blog")...

  1. markai
    markai Neues Mitglied
    Ich würde gerne in meinen Blog Posts speichern können. Dazu habe ich folgende Entities.

    Meinen Blog:

    Code (Java):

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

        private static final long serialVersionUID = 1L;
       
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
       
        @NotBlank
        @Column(nullable = false, unique = true)
        private String name;
       
        @Lob
        @Column(columnDefinition = "CLOB")
        private String description;
       
        @OneToMany(mappedBy = "blog")
        private List<Post> posts = new ArrayList<Post>();
     
    und meine Posts:
    Code (Java):

    @Entity
    @Table(name = "Post")
    public class Post implements Serializable {
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
       
        //...

        @ManyToOne @JoinColumn(name = "BLOG_ID", nullable = false)
        private Blog blog;
     
    Nun habe ich folgenden Test geschrieben:
    Code (Java):

        @Test
        public void testSavePost() {
            Blog blog1 = testBlogs.get(0);
            Post post = new Post("Title", "Test Content", blog1);
            login("user1@test.com", "topsecret1");
            postService.save(post);
     
    Mein Problem ist, dass mein postService den Post nicht persistieren kann wenn ich einen Blog mit übergebe. In der Exception steht was von "integrity constraint violation: foreign key no action; ... table: POST". Leider kenn ich mich nicht so gut aus dass ich diese deuten könnte ;(

    Fürs ORM verwende ich Hibernate.

    Hier die ganze Output:

    Code (Java):

    javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
        at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1397)
        at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:108)
        at at.company.aim.blog.services.AbstractTestBase.clearDatabase(AbstractTestBase.java:66)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
        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.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
        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:309)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
        at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
        at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
        at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
    Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
        at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136)
        at org.hibernate.hql.internal.ast.exec.BasicExecutor.execute(BasicExecutor.java:103)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:414)
        at org.hibernate.engine.query.spi.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:282)
        at org.hibernate.internal.SessionImpl.executeUpdate(SessionImpl.java:1290)
        at org.hibernate.internal.QueryImpl.executeUpdate(QueryImpl.java:116)
        at org.hibernate.ejb.QueryImpl.internalExecuteUpdate(QueryImpl.java:196)
        at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:99)
        ... 34 more
    Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: foreign key no action; FK_KTXW0U65IC5COCUEQWQ1F6A69 table: POST
        at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
        at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
        at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
        at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
        ... 41 more
    Caused by: org.hsqldb.HsqlException: integrity constraint violation: foreign key no action; FK_KTXW0U65IC5COCUEQWQ1F6A69 table: POST
        at org.hsqldb.error.Error.error(Unknown Source)
        at org.hsqldb.StatementDML.performReferentialActions(Unknown Source)
        at org.hsqldb.StatementDML.delete(Unknown Source)
        at org.hsqldb.StatementDML.executeDeleteStatement(Unknown Source)
        at org.hsqldb.StatementDML.getResult(Unknown Source)
        at org.hsqldb.StatementDMQL.execute(Unknown Source)
        at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
        at org.hsqldb.Session.execute(Unknown Source)
        ... 44 more
     
     
  2. Vielleicht hilft dir dieser Kurs hier weiter --> (hier klicken)
  3. redJava99
    redJava99 Mitglied
    Beim Versuch, den Post zu speichern, ist der darin referenzierte blog noch nicht persistiert.
    Wenn nun versucht wird, den Post zu speichern, muss es aber eine Referenz (den ForeignKey) auf den Blog geben. D.h. du kannst den Post nicht speichern, ohne den Blog vorher zu speichern.
    Dafür gibt es 2 Möglichkeiten:
    1.: Du speicherst den Blog vorher manuell und übergibst dann das persistierte Objekt an den Post
    oder 2.: Du ergänzt die Annotation
    Code (Text):
    @ManyToOne
    mit
    Code (Text):
    (cascade = CascadeType.ALL)
    . Die Annotation veranlasst Hibernate dazu, den Blog zu persistieren, sobald der Post persistiert wird (so, wie du das intuitiv wahrscheinlich angenommen hattest).
     
  4. markai
    markai Neues Mitglied
    Danke für die Antwort! Der Blog ist persistent (Sorry, konntest du nicht wissen).

    Code (Java):

        @Before
        public void setUp() {
            testUsers = createTestUsers(5);
            testBlogs = createTestBlogs(testUsers);
        }

        protected List<User> createTestUsers(int numberOfUsers) {
            List<User> result = new ArrayList<User>();
            for (int i = 1; i <= numberOfUsers; i++) {
                User user = new User("user" + i + "@test.com", "First" + i, "Last" + i, "User" + i, "topsecret" + i);
                userService.save(user);
                result.add(user);
            }
            return result;
        }
       
            protected List<Blog> createTestBlogs(List<User> users) {
            List<Blog> blogs = new ArrayList<Blog>(users.size());
            int i = 1;
            for(User user: users) {
                login(user.getEmail(), "topsecret"+i);
                Blog blog = new Blog("User"+i+"'s Blog", TEST_CONTENT);
                blogService.save(blog);
                blogs.add(blog);
                i++;
            }
            return blogs;
        }
     
     
  5. redJava99
    redJava99 Mitglied
    Okay, zweiter Versuch:

    mit
    Code (Java):
    protected List<Blog> createTestBlogs(List<User> users) {
    //...
     Blog blog = new Blog("User"+i+"'s Blog", TEST_CONTENT);
     blogService.save(blog);
    //...
    }
    kommt der Blog zwar in die Datenbank, aber in deine Liste steckst du danach das "alte" Objekt, nicht das Objekt aus der Datenbank ("detached entity").

    Probiere es mit
    Code (Java):
    protected List<Blog> createTestBlogs(List<User> users) {
    //...
     Blog blog = new Blog("User"+i+"'s Blog", TEST_CONTENT);
     blog = blogService.save(blog);
    //...
    }
    wobei die Save Methode im BlogService etwa so aussieht:
    Code (Java):
    public Blog save(Blog saveMe) {
    //...
     Blog persistedBlog= myEntiyManager.merge(saveMe);
     myEntiyManager.getTransaction().commit();
     return persistedBlog;
    //...
    }
     
  6. markai
    markai Neues Mitglied
    Hmm dann krieg ich genau den selben Fehler...

    Code (Java):

        @Test
        public void testSavePost() {
            User u = new User("user1@test.com", "firstname", "lastname", "nickname", "topsecret1");
            userService.save(u);
            Blog blog1 = new Blog("name", "description");
            login("user1@test.com", "topsecret1");
            blogService.save(blog1);
            Post post = new Post("Title", "Test Content", blog1);
            postService.save(post);
        }
     
    meine save-Methode im Blog sieht so aus.

    Code (Java):

    @Transactional
    @Named
    public interface BlogService extends Repository<Blog, Long>{

        @PostAuthorize("hasRole('ROLE_ADMINISTRATOR') or returnObject.owner.email == authentication.name")  
        public Blog save(Blog blog);
     
    Stimmen meine Annotations im Entity?
     
  7. markai
    markai Neues Mitglied
    Fehler war an einer ganz anderen Stelle im Code. Programm funktioniert jetzt :toll:

    Trotzdem danke für die Hilfe!
     
Die Seite wird geladen...

@ManyToOne ConstraintViolationException - Ähnliche Themen

Anfängerfrage: h:selectOneMenu (JSF 2.0), @ManyToOne Annotation in Entity (JPA 2.0)
Anfängerfrage: h:selectOneMenu (JSF 2.0), @ManyToOne Annotation in Entity (JPA 2.0) im Forum Allgemeines EE
Hybernate Criteria API bei @ManyToOne
Hybernate Criteria API bei @ManyToOne im Forum Data Tier
java.sql.SQLIntegrityConstraintViolationException nach zweitem persist
java.sql.SQLIntegrityConstraintViolationException nach zweitem persist im Forum Data Tier
Thema: @ManyToOne ConstraintViolationException