Bidirectional @Any mapping?

Is there a way to define the inverse of an @Any mapping, some kind of @AnyToMany?
I’ve been looking for this for some time, but I may be missing something obvious.

The model concerns Tasks that need to be processed. These tasks contain Subtasks, and the processing may generate TaskErrors, on the level of both Tasks and Subtasks. It looks something like this:

public interface Excepted { ... }

@Entity
public class TaskException {
    @Any
    @AnyDiscriminator(DiscriminatorType.STRING)
	@AnyDiscriminatorValues({
			@AnyDiscriminatorValue(discriminator = "Task",
                                   entity = Task.class),
			@AnyDiscriminatorValue(discriminator = "SubTask",
                                   entity = SubTask.class)})
    @AnyKeyJavaClass(String.class)
    @Column(name = "excepted_type")
    @JoinColumn(name = "excepted_id")
	private Excepted excepted;

    ...
}

@Entity
public class Task implements Excepted {
    @OneToMany(mappedBy = "excepted")
    private List<TaskException> exceptions =
        new ArrayList<TaskException>();

    ...
}

@Entity
public class SubTask implements Excepted {
    @OneToMany(mappedBy = "excepted")
    private List<TaskException> exceptions =
        new ArrayList<TaskException>();

    ...
}

TaskException.excepted works, but the naive @OneToMany doesn’t, it yields a MappingException ( collection foreign key mapping has wrong number of columns). I have the feeling that the solution can’t be that hard, the SQL query to fetch a (Sub)Task’s exceptions is trivial. Some black magic involving @Join... may solve this, but I hope there’s a clean and compact annotation I’ve overlooked.

Some background: the application I’m working on is mostly written in PHP using Laravel, but we need to do some SOAP communication that we only know how to do in Java. The easiest solution we could think of is to have the PHP code write request data to the database, have a small Java program read these data and send the requests over SOAP and write the responses back to db, and further process the responses in PHP. So I need to design a database model that would be approached from two sides: by Eloquent (Laravel’s ORM) and by Hibernate. The bidirectional @Any I’m looking for is quite straightforward in Eloquent (morphMany method of the Model class), I would like to translate this to Java. :slight_smile:

You can create a feature request for this. In the meantime, you just need to use the following annotations instead:


@Entity
public class Task implements Excepted {
    @OneToMany
    @JoinColumn(name = "excepted_id")
    private List<TaskException> exceptions =
        new ArrayList<TaskException>();

    ...
}

Thanks beikov, for the fast reply! Sure is a lot more compact than my rambling.

Anyway, this is almost what I need. The number of columns is correct now. But Task.exceptions now also contains the exceptions of a SubTask that happens to have the same primary key value. If I add @Where(clause = "excepted_type = 'Task'") it seems to work as intended. That’s the cleanest solution at this moment, right?

I’ll try to create a feature request tomorrow.

Yes, that’s as good as it gets for now.

The feature request is here. Thanks again for your kind help!

1 Like