I search a way to map a many-to-many association table with extra column(s) with hibernate in xml files configuration.
Assuming with have two table 'a' & 'c' with a many to many association with a column named 'extra'. Cause I didn't find any complete example, here is my code. Hope it will help :). 
First here is the Java objects.
public class A implements Serializable{  
    protected int id;
    // put some others fields if needed ...   
    private Set<AC> ac = new HashSet<AC>();
    public A(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public Set<AC> getAC() {
        return ac;
    }
    public void setAC(Set<AC> ac) {
        this.ac = ac;
    }
    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        final int prime = 97;
        int result = 1;
        result = prime * result + id;
        return result;
    }
    /** {@inheritDoc} */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof A))
            return false;
        final A other = (A) obj;
        if (id != other.getId())
            return false;
        return true;
    }
}
public class C implements Serializable{
    protected int id;
    // put some others fields if needed ...    
    public C(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        final int prime = 98;
        int result = 1;
        result = prime * result + id;
        return result;
    }
    /** {@inheritDoc} */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof C))
            return false;
        final C other = (C) obj;
        if (id != other.getId())
            return false;
        return true;
    }
}
Now, we have to create the association table. The first step is to create an object representing a complex primary key (a.id, c.id).
public class ACId implements Serializable{
    private A a;
    private C c;
    public ACId() {
        super();
    }
    public A getA() {
        return a;
    }
    public void setA(A a) {
        this.a = a;
    }
    public C getC() {
        return c;
    }
    public void setC(C c) {
        this.c = c;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((a == null) ? 0 : a.hashCode());
        result = prime * result
                + ((c == null) ? 0 : c.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ACId other = (ACId) obj;
        if (a == null) {
            if (other.a != null)
                return false;
        } else if (!a.equals(other.a))
            return false;
        if (c == null) {
            if (other.c != null)
                return false;
        } else if (!c.equals(other.c))
            return false;
        return true;
    }
}
Now let's create the association object itself.
public class AC implements java.io.Serializable{
    private ACId id = new ACId();
    private String extra;
    public AC(){
    }
    public ACId getId() {
        return id;
    }
    public void setId(ACId id) {
        this.id = id;
    }
    public A getA(){
        return getId().getA();
    }
    public C getC(){
        return getId().getC();
    }
    public void setC(C C){
        getId().setC(C);
    }
    public void setA(A A){
        getId().setA(A);
    }
    public String getExtra() {
        return extra;
    }
    public void setExtra(String extra) {
        this.extra = extra;
    }
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        AC that = (AC) o;
        if (getId() != null ? !getId().equals(that.getId())
                : that.getId() != null)
            return false;
        return true;
    }
    public int hashCode() {
        return (getId() != null ? getId().hashCode() : 0);
    }
}
At this point, it's time to map all our classes with hibernate xml configuration.
A.hbm.xml and C.hxml.xml (quiete the same).
<class name="A" table="a">
        <id name="id" column="id_a" unsaved-value="0">
            <generator class="identity">
                <param name="sequence">a_id_seq</param>
            </generator>
        </id>
<!-- here you should map all others table columns -->
<!-- <property name="otherprop" column="otherprop" type="string" access="field" /> -->
    <set name="ac" table="a_c" lazy="true" access="field" fetch="select" cascade="all">
        <key>
            <column name="id_a" not-null="true" />
        </key>
        <one-to-many class="AC" />
    </set>
</class>
<class name="C" table="c">
        <id name="id" column="id_c" unsaved-value="0">
            <generator class="identity">
                <param name="sequence">c_id_seq</param>
            </generator>
        </id>
</class>
And then association mapping file, a_c.hbm.xml.
<class name="AC" table="a_c">
    <composite-id name="id" class="ACId">
        <key-many-to-one name="a" class="A" column="id_a" />
        <key-many-to-one name="c" class="C" column="id_c" />
    </composite-id>
    <property name="extra" type="string" column="extra" />
</class>
Here is the code sample to test.
A = ADao.get(1);
C = CDao.get(1);
if(A != null && C != null){
    boolean exists = false;
            // just check if it's updated or not
    for(AC a : a.getAC()){
        if(a.getC().equals(c)){
            // update field
            a.setExtra("extra updated");
            exists = true;
            break;
        }
    }
    // add 
    if(!exists){
        ACId idAC = new ACId();
        idAC.setA(a);
        idAC.setC(c);
        AC AC = new AC();
        AC.setId(idAC);
        AC.setExtra("extra added"); 
        a.getAC().add(AC);
    }
    ADao.save(A);
}