openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Henno Vermeulen <he...@huizemolenaar.nl>
Subject RE: Bi-Directional Relation and Lazy
Date Tue, 25 Sep 2012 10:22:52 GMT
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-pro@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);
		}
	}			
Mime
View raw message