Nofollow SHOULD help from a pure outbound/inbound link perspective, but I haven't tested this personally.  If Google isn't seeing site B sending site A links, you should be good.

But I think there's more to it than just blindly saying if StackExchange is doing it, there isn't a problem if you do link them all to each other.  I think you have to weigh multiple factors, three of which are the type (of content) of sites in your network, their subject matter, and the number of links created.  Is all the content created by you?  Is it an aggregator site?  Is it a Blogger site with copy and pastes from other sites, with nothing but Adsense on it?  If the content is original, you're better off, but I don't think completely safe from penalties.  As Aurelio De Rosa mentioned above, linking sites with similar subject matter will be more beneficial than just linking all 20 very different sites together.  And if we're only talking about a small percentage of your overall inbound links, it probably won't hurt.

I'm facing a similar issue with my network of sites (all related to one industry) that you're trying to avoid.  It's made up of 6 sites, of which 4 are included in the footer of every page on those 4 sites.  After Googles April/May algorithm update, we saw a dramatic decrease in keyword rankings and actually dropped off the first 10 pages completely for a couple of them (after being on the first page).  We  received warnings from Google that our page exhibited "unnatural inbound links", of which 2 of the 4 sites I mentioned numbered 350K+ inbound links.  One of those sites is a news aggregator, all others are UGC and original content.  After making changes and submitting a couple reconsideration requests, we're still seeing the warnings.  Our next test is the nofollow approach you suggested.  We'll start by reducing those 350k links by some percentage and hope for something positive from Google.

Using nofollow when crosslinking my own sites
I've been having an issue with Hibernate 4  that did not happen in Hibernate 3.  I'm testing a base dao class which has generic methods for saving, querying, etc.. (not it's not homework).  I'm using an embedded derby connection with hibernate.hbm2ddl.auto=create-drop for testing purposes.

EDIT:  Fixing cascadeType.  Still the same behavior.  Even if i add in all the available cascade types from the CascadeType enum, it still fails, unless I put CascadeType.ALL.  Not sure what ALL has that you can't specifically enumerate.

In my tests, I have following mapped classes:

@Entity
@Table(name="FOO_CHILD")
public class FooChild {
    @Id
    @Column(name="FOO_ID")
    private Long id;

    @Column(name="NAME")
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@Entity
@Table(name="FOO_PARENT")
public class FooParent {
    @Id
    @Column(name="FOO_PARENT_ID")
    private Long id;

    @Column(name="NAME")
    private String name;

    @Fetch(FetchMode.SELECT)
    @Type(type="long")
    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(name="FOO_PARENT_FOO",
            joinColumns={@JoinColumn(referencedColumnName="FOO_PARENT_ID")},
            inverseJoinColumns={@JoinColumn(referencedColumnName="FOO_ID")})
    private List&lt;Foo&gt; fooChild;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List&lt;Foo&gt; getFooChild() {
        return fooChild;
    }

    public void setFooChild(List&lt;Foo&gt; fooChild) {
        this.fooChild = fooChild;
    }
}


And then i try to save:

FooChild fooChild = new FooChild();
fooChild.setId(1L);
fooChild.setName("fooChild");

FooParent fooParent = new FooParent();
fooParent.setId(1L);
fooParent.setName("fooParent");
fooParent.setFooChild(new ArrayList&lt;FooChild&gt;(Arrays.asList(fooChild)));

session.save(fooParent);
session.flush();
session.clear();


I get the following trace:

org.hibernate.exception.ConstraintViolationException: INSERT on table 'FOO_PARENT_FOO' caused a violation of foreign key constraint 'FKF18290CAECA19CB8' for key (1).  The statement has been rolled back.
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
...


I noticed the following sql being executed:

Hibernate: 
    insert 
    into
        foo_parent
        (name, foo_parent_id) 
    values
        (?, ?, ?, ?)
Hibernate: 
    insert 
    into
        foo_parent_foo
        (foo_parent, foo_child) 
    values
        (?, ?)


It seems it's trying to insert into the collection before cascading the save down to the FooChild object.

If i change FooParent to have this:

@OneToMany(cascade={CascadeType.ALL})


The problem goes away.

As i said, this works with hibernate 3, so i'm not sure why it's behaving differently.
