-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: @Embeddedid with one field being auto_increment
PostPosted: Fri Feb 24, 2006 5:08 pm 
Newbie

Joined: Sun Jul 24, 2005 4:17 pm
Posts: 7
Hello,

I have a table with Integer + String composite key
integer being the auto_increment field.

MYSQL supports this kind of primary key so it generates the integer field.

But I cannot get it read back into the entity after and insert.

I tried various types of annotations with @IdClass and @EmbeddedId...

I also tried to implement an interceptor and implemented the istransient method.
is this supported?

Regards,
Ceylan


Top
 Profile  
 
 Post subject: Solved!!! @Embeddedid with one field being auto_increment
PostPosted: Fri Feb 24, 2006 10:57 pm 
Newbie

Joined: Sun Jul 24, 2005 4:17 pm
Posts: 7
OK, After browsing / debugging the hibernate src a lot, and trying and trying,
I guess this is not possible.

So, I got down for doing it the hard (easy :) ) way. Actually it could have taken less time to implement it this way right away rather then digging into the code.

For those having problem with composite keys with auto increment fields in them, here's the solution:

1) Create an Entity for sequence manupulation

@Entity
@Table(name = "uuid")
public class UUID {
@Id
@Column(name = "ENTITY")
private String key;

@Column(name = "VALUE")
private int value;

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public int getValue() {
return value;
}

public void setValue(int value) {
this.value = value;
}
}

2) Create a generator class
public class IDVenueGenerator implements IdentifierGenerator, Configurable {

static Logger logger = Logger.getLogger(IDVenueGenerator.class);

static Object initLock = new Object();

private String entityName;

/*
* (non-Javadoc)
*
* @see org.hibernate.id.IdentifierGenerator#generate(org.hibernate.engine.SessionImplementor,
* java.lang.Object)
*/
public Serializable generate(SessionImplementor sessionImplementor,
Object object) throws HibernateException {

VenueAuditable venueEntity;

if (object instanceof VenueAuditable) {
venueEntity = (VenueAuditable) object;
} else
throw new RuntimeException("Object [" + entityName
+ "] key cannot be generated by IDVenueKey generator! ");

Session session = ((Session) sessionImplementor).getSessionFactory()
.openSession();
session.beginTransaction();
try {
UUID uuid = (UUID) session.get(UUID.class, entityName,
LockMode.UPGRADE);
if (uuid == null) {
logger.info("No key for " + entityName
+ "! Attempting to create...");
uuid = initializeUUID(session);
}

uuid.setValue(uuid.getValue() + 1);

return new IDVenueKey(venueEntity.getInitialVenue(), uuid
.getValue());
} finally {
try {
if (session.getTransaction().isActive())
session.getTransaction().commit();
} catch (Exception e) {
}
}
}

/**
* Initializes a UUID for the entitiy for one time only
*
* @param session
* @return
*/
private UUID initializeUUID(Session session) {
UUID uuid = null;

synchronized (initLock) {
logger.info("Entered into synchronized section to initialize uuid");
uuid = (UUID) session.get(UUID.class, entityName, LockMode.UPGRADE);
if (uuid == null) {
logger.info("Initializing the uuid");
uuid = new UUID();
uuid.setKey(entityName);
uuid.setValue(0);

session.save(uuid);
logger.info("UUID initialized successfully. Committing... ");
session.getTransaction().commit();
logger
.info("Committed successfully. Restoring the original transaction...");
session.beginTransaction();
} else {
logger
.info("UUID has just been initialized by another thread...");
}

logger.info("Leaving the synchronized section");
}

return uuid;

} /*
* (non-Javadoc)
*
* @see org.hibernate.id.Configurable#configure(org.hibernate.type.Type,
* java.util.Properties, org.hibernate.dialect.Dialect)
*/

public void configure(Type type, Properties params, Dialect d)
throws MappingException {

entityName = params.getProperty(ENTITY_NAME);
}

}

3) Annotate your classes like this
@GenericGenerator(name = "IDVenueKey", strategy = "com.ytg.bilette.model.IDVenueGenerator"

4) Annotate your embeddedID field like this
@GeneratedValue(generator = "IDVenueKey")
@EmbeddedId

Of course, this solutions assumes you stop using the auto_increment fields.
If you have en existing schema and cannot manupulate the structure then you may modify this code to first insert a dummy record into the table in question and then read the insert id back and pass it out from the generator...

happy coding...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.