If I understand your question well, in this use case you need to fetch Tasks 
and only need to traverse from Task to TaskState but not vice versa. I guess 
your main concern is the performance or perhaps memory usage of the query. I 
don't really see a major performance drawback for having OpenJPA also fill 
TaskState.getTask() because if I'm correct OpenJPA will translate your JPQL 
query to exactly one (maybe two?) native query. You can verify this by setting 
the logger to TRACE level. 

Because this query selects all Tasks and TaskStates, OpenJPA will have already 
fetched all Tasks for each TaskState so it does not have to do an extra query 
for filling TaskState.getTask. The performance of filling this should be 
negligible compared to the performance of hitting the database.

If you never have the need to traverse from TaskState to Task, you can make the 
relation unidirectional by removing the TaskState.State and moving the 
@JoinColumn annotation to Task.getTaskState(). This still maps to a foreign key 
column in the database table for TaskState, even though it is in the Java code 
for the Task entity.

Hope this helps,
Henno


-----Oorspronkelijk bericht-----
Van: Chris Pro [mailto:chris-...@gmx.net] 
Verzonden: maandag 24 september 2012 16:48
Aan: users@openjpa.apache.org
Onderwerp: Bi-Directional Relation and Lazy

Hello

I've two JPA-Entities (OpenJPA 2.2.0): Task and TaskState.
TaskState have a foreign key on Task. Therefore I marked the relation 
TaskState.getTask() as Lazy. The relation opposite Task.getTaskState() is Lazy 
too (Default for OneToMany). So when I write a JPQL like that in an EJB both 
relations are filled: 
SELECT t FROM Task t LEFT JOIN FETCH t.TaskState

With that query both relations are filled. But the relation TaskState.getTask() 
should be lazy and not filled. The problem is, that that query 
result-list-object is very big, because of the bi-directional: Task have x 
TaksState -> TaskState have the Task -> Task have x TaksState -> and so one. 

Is there a way, to prevent the loading/filling of TaskState.getTask()?

Would be great, if someone could help me.


@Entity
public class Task implements Serializable
{

    private static final long serialVersionUID = 1L;

    public Task()
    {}

        // ...
        
        private List<TaskState> TaskState;

    @OneToMany(mappedBy = "task")
    public List<TaskState> getTaskState()
    {
        return TaskState;
    }

    public void setTaskState(final List<TaskState> TaskState)
    {
        this.TaskState = TaskState;
    }   
}


@Entity
public class TaskState implements Serializable, Comparable<TaskState>
{
    private static final long serialVersionUID = 1L;

    public TaskState()
    {}
        
    private Task task;

    @ManyToOne(fetch = FetchType.LAZY)
    @javax.persistence.JoinColumn(name = "state_task_Id", referencedColumnName 
= "task_Id", nullable = false)
    public Task getTask()
    {
        return task;
    }

    public void setTask(final Task task)
    {
        this.task = task;
    }   
}



// EJB
    public Collection<Task> findAllTasks() throws BBException
    {
        try
        {
            Query query = em.createQuery("SELECT t FROM Task t LEFT JOIN FETCH 
t.TaskState");
                        Collection<Task> tasks = query.getResultList();
                        return tasks;
                        // Why are the tasks on TaskState.getTaskState() are 
also filled with Tasks-Objects?
        }
        catch (Exception ex)
                {
                        throw new BBException(ex);
                }
        }                       

Reply via email to