Спящий однотомный картограф - PullRequest
5 голосов
/ 07 сентября 2010

Я пытаюсь отобразить отношение впервые. Я нашел много способов пойти.

Есть два класса: - Проект (родитель) - Заявка (детская)

Таким образом, один проект может иметь несколько приложений, но одно приложение относится только к одному проекту.

Я построил их следующим образом:

Project.java

 import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToMany;

    @Entity
    public class Project {

     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private int id;
        @OneToMany(cascade = CascadeType.ALL)
        @JoinColumn(name = "project_id", nullable=false)
        @org.hibernate.annotations.IndexColumn(name = "project_index")
        List<Application> applications = new ArrayList<Application>();

        [get and set methods...]
        }

Application.java

import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;

    @Entity
    public class Application {

         @Id
         @GeneratedValue(strategy = GenerationType.IDENTITY)
         private int id;

            @ManyToOne
            @JoinColumn(name = "project_id", updatable = false, insertable = false, nullable=false)
            private Project project;

        [get and set methods...]
     }

... но, к сожалению, я получил исключение, с которым не могу справиться:

javax.servlet.ServletException: org.hibernate.PropertyValueException: not-null property references a null or transient value: ....common.entities.Application._applicationsBackref
 javax.faces.webapp.FacesServlet.service(FacesServlet.java:321)
 org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:359)
 org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:275)
 org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
 org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
 org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:343)
 org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:272)
 org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:83)

root cause

javax.faces.el.EvaluationException: org.hibernate.PropertyValueException: not-null property references a null or transient value: ....common.entities.Application._applicationsBackref
 javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:98)
 com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:98)
 javax.faces.component.UICommand.broadcast(UICommand.java:311)
 javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:781)
 javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246)
 com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77)
 com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
 com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
 javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
 org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:359)
 org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:275)
 org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
 org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
 org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:343)
 org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:272)
 org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:83)

root cause

org.hibernate.PropertyValueException: not-null property references a null or transient value: ....common.entities.Application._applicationsBackref
 org.hibernate.engine.Nullability.checkNullability(Nullability.java:95)
 org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:313)
 org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
 org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
 org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
 org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
 org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
 org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
 org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)

Где моя ошибка? Я имею в виду, что нет ничего нулевого. Только на стороне проекта


Когда я удаляю @JoinColumn на стороне-владельце, возникает исключение:

java.sql.SQLException: Field 'project_id' doesn't have a default value

Спасибо, Паскаль

Ответы [ 3 ]

19 голосов
/ 07 сентября 2010

В вашем отображении есть несколько вещей, которые нужно исправить.

  • Ваша связь является двунаправленной, вам нужно использовать атрибут mappedBy на стороне "One" (или вы получите две однонаправленные ассоциации), чтобы определить поле, которое "владеет" отношением на стороне-владельце ( сторона, которая содержит внешний ключ, т. е. сторона «многие» (один-ко-многим).
  • Аннотация @JoinColumn должна определяться только на стороне владельца, а не на обеих сторонах.
  • Если вы используете версию Hibernate, совместимую с JPA 2.0 (т.е. Hibernate 3.5+), предпочтите стандартную аннотацию @OrderColumn специфичной для Hibernate @IndexColumn
  • Я не уверен, что понимаю, почему вы определили @JoinColumn как полностью доступный только для чтения с updatable = false, insertable = false, nullable=false, это не звучит уместно.

Итак, ваши отображения становятся (при условии, что вы используете JPA 2.0):

@Entity
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @OneToMany(cascade = CascadeType.ALL, <b>mappedBy="project")
    @OrderColumn(name = "project_index")</b>
    List<Application> applications = new ArrayList<Application>();

    // getters, setters
}

И

@Entity
public class Application {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @ManyToOne
    @JoinColumn(name = "project_id")
    private Project project;

    // getters, setters
 }

И поскольку ваша связь двунаправленная, не забудьте установить обе стороны ссылки при создании графа объектов:

Project p = new Project();
Application a = new Application();
a.setProject(p);
p.getApplications().add(a);
em.persist(p);

Но я бы порекомендовал создать методы управления ссылками в ваших сущностях для установки обеих сторон ссылки, например,

@Entity
public class Project {
    ...
    public void addToApplications(Application app) {
        this.applications.add(app);
        app.setProject(this);
    }
    ...
}

Ресурсы

Ссылки * * тысяча пятьдесят-одна спецификация JPA 1.0 Раздел 2.1.8.2 «Двунаправленные отношения« Много-один-одно-много »» Раздел 9.1.24 «Аннотация OneToMany» Раздел 9.1.22 «Аннотации ManyToOne» спецификация JPA 2.0 Раздел 11.1.39 «Порядок аннотации столбца»

4 голосов
/ 07 сентября 2010

@JoinColumn аннотация не нужна с обеих сторон. На самом деле, вы должны ставить это только на сторону отношений.

Кроме того, вы должны описать эту вещь, как показано ниже,

@JoinColumn(name = "project_id", updatable = false, insertable = false, nullable=false)

Это совершенно бессмысленно. На самом деле это означает, что вы не хотите обновлять его, не хотите вставлять его или иметь нулевое значение.

Кроме того, вы пропускаете аннотацию @Column в полях Id, если имя фактического столбца не id.

0 голосов
/ 14 декабря 2017

Сущность

@Table(name="Customer_v1")

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)

public class Customer implements Serializable{                

                @Id

                @Column(name="cust_id")

                protected int custId;

 ------------------------------------------------

@Entity

@DiscriminatorValue(value = "N")

public class NewCustomer extends Customer {}

 

@Entity

@DiscriminatorValue( value="E")

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