One approach that comes to my minds would be using views.
Step 1: find all combinations of from_table, from_field, to_table, to_field. E.g.
Code:
select count(*), from_table, from_field, to_table, to_field group by from_table, from_field, to_table, to_field
(the count(*) is there so you can see those associations that exists just once, and maybe decide on another strategy to handle that case).
Step 2: for each combination of from_table/from_field/to_table/to_field, create a view à la
Code:
select from_key,to_key from associations where from_table = "t1" and from_field = "f1" and to_table = "f2" and to_field = "t2"
This view will serve as your association table.
Step 3: reverse engineer as usual with association tables. Hibernate reveng doesn't care much whether the association table is actually a view or not.
Some caveats apply:
A) Make sure that either the views are insertable and updatable, or that your code doesn't try to do inserts resp. updates. It depends on the capabilities of the database whether these views are or not.
B) You may have to point reveng in the right direction to make it figure out what view is an association table for what combinations of tables. I can't help with that because I never reverse engineered a database with many-to-many associations; one problem that I have seen that might come up again is that Reveng needs to know what the primary keys are, but the JDBC driver does not provide that information, hence the need for explicitness.
C) In general, reveng is a rather awkward and cumbersome process. It's worth it because it makes less errors than a reverse-engineering human would, but reveng does fight back.