I have following Entities:
Code:
/*CREATE TABLE `card_type_tmp` (
`id` int(11) NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;*/
@Entity
@org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.TRANSACTIONAL)
@Table(name = "card_type_tmp")
public class CardType {@Id
@GeneratedValue
@Column(name = "id", nullable = false, updatable = false)
private int id = 0;
@OneToMany(cascade = { CascadeType.REMOVE }, mappedBy = "cardType", fetch = FetchType.LAZY)
private List<EmDefinition> emColl = new ArrayList<EmDefinition>();
public List<EmDefinition> getEmColl() {
return emColl;
}
public int getId() {
return id;
}
Code:
/*CREATE TABLE `em_def_tmp` (
`id` int(11) NOT NULL auto_increment,
card_type_id int(11),
dev_param_id int(11),
PRIMARY KEY (`id`),
CONSTRAINT cardtypeFK FOREIGN KEY (card_type_id) REFERENCES card_type_tmp(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;*/
@Entity
@Table(name = "em_def_tmp")
@NamedQuery(name = EmDefinition.NQ_FIND_BY_DEVICE_PARAM_ID_AND_CARD_TYPE_ID, query = "SELECT e FROM EmDefinition e WHERE e.dparamId=:dParamId AND e.cardType.id = :cardTypeId")
public class EmDefinition{
public static final String NQ_FIND_BY_DEVICE_PARAM_ID_AND_CARD_TYPE_ID = "EmDefinition,findByDeviceParamAndCardType";
@Id
@GeneratedValue
@Column(name = "id", nullable = false)
private int id = 0;
@JoinColumn(name = "card_type_id", referencedColumnName = "id", updatable = false)
@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
private CardType cardType;
@Column(name = "dev_param_id")
private int dparamId;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public CardType getCardType() {
return cardType;
}
public void setCardType(CardType cardType) {
this.cardType = cardType;
}
public int getDparamId() {
return dparamId;
}
public void setDparamId(int dparamId) {
this.dparamId = dparamId;
}
}
and two sessionBeans
Code:
@Stateless
public class SessionBean1 implements SessionBean1Local, SessionBean1Remote {
@PersistenceContext(unitName = "TestPU")
private EntityManager em = null;
@EJB
@org.jboss.annotation.IgnoreDependency
private SessionBean2Local sessionL = null;
private int addDefinitions(CardType card) {
//System.out.println("the 'size' value is: " + card.getEmColl().size()); //when uncommenting this printing - the result is 6 always - WHY?????
sessionL.addDefinitions(card);
int i = 0;
System.out.println("the 'size' value is: " + card.getEmColl().size());
for (EmDefinition def : card.getEmColl()) {
System.out.println("definitionId:" + def.getId()); //there is 7 objects printed on screen (the last two are the same)
i++;
}
System.out.println("the 'i' value is: " + i);
return i;
}
private CardType createCardType() {
CardType cardType = new CardType();
em.persist(cardType);
return cardType;
}
public int createCard() {
return this.createCardType().getId();
}
public int addDefinitions(int cardTypeId) {
CardType card = em.find(CardType.class, cardTypeId);
return this.addDefinitions(card);
}
}
Code:
@Stateless
public class SessionBean2 implements SessionBean2Local {
@PersistenceContext(unitName = "AirSyncPU")
private EntityManager em = null;
@Override
public void addDefinitions(CardType card) {
for (int i = 0; i < 6; i++) {
this.addDefinition(card, i);
}
}
private void addDefinition(CardType card, int dParamId) {
EmDefinition def = findByDeviceParamIdAndCardTypeId(dParamId, card.getId());
if (def == null) {
def = new EmDefinition();
def.setCardType(card);
def.setDparamId(dParamId);
def.setId(0);
card.getEmColl().add(def);
em.persist(def);
} else {
def.setDparamId(dParamId);
}
/////////////////////// WRONG BEHAViours. WHY?????????????????????
//EmDefinition def = null;
// em.persist(def);
//card.getEmColl().add(def);
//results with 12 objects on the list
//EmDefinition def = findByDeviceParamIdAndCardTypeId(dParamId, card.getId());
// em.persist(def);
//card.getEmColl().add(def);
//results with 7 objects on the list
//EmDefinition def = findByDeviceParamIdAndCardTypeId(dParamId, card.getId());
//card.getEmColl().add(def);
//em.persist(def);
//results with 7 of object on the list - the order does not matter
}
private EmDefinition findByDeviceParamIdAndCardTypeId(int dParamId, int cardTypeId) {
Query q = em.createNamedQuery(EmDefinition.NQ_FIND_BY_DEVICE_PARAM_ID_AND_CARD_TYPE_ID);
q.setParameter("cardTypeId", cardTypeId);
q.setParameter("dParamId", dParamId);
try {
return (EmDefinition) q.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
}
My test
Code:
@Test
public void test() throws NamingException {
int card = getSessionBean1Remote().createCard();
int definitionsNo= getSessionBean1Remote().addDefinitions(card);
System.out.println(definitionsNo);
}
while calling getSessionBean1Remote().addDefinitions(card); I add by hand ONLY 6 definitions (database is filled with 6 definitions) but... in SessionBean1 where I call card.getEmColl().size() and print it to the logs there is 7 objects and test results with returned 'definitionsNo' equals to 7.
I turned hibernate logs to TRACE and this is what I got:
2012-01-18 08:22:40,294 TRACE [org.hibernate.event.def.DefaultInitializeCollectionEventListener] initializing collection [com.tests.dupliactes.CardType.emColl#28]
2012-01-18 08:22:40,294 TRACE [org.hibernate.event.def.DefaultInitializeCollectionEventListener] checking second-level cache
2012-01-18 08:22:40,294 TRACE [org.hibernate.event.def.DefaultInitializeCollectionEventListener] collection not cached
2012-01-18 08:22:40,294 DEBUG [org.hibernate.loader.Loader] loading collection: [com.tests.dupliactes.CardType.emColl#28]
2012-01-18 08:22:40,294 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2012-01-18 08:22:40,294 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
2012-01-18 08:22:40,294 DEBUG [org.hibernate.SQL] select emcoll0_.card_type_id as card3_1_, emcoll0_.id as id1_, emcoll0_.id as id1_0_, emcoll0_.card_type_id as card3_1_0_, emcoll0_.dev_param_id as dev2_1_0_ from em_def_tmp emcoll0_ where emcoll0_.card_type_id=?
2012-01-18 08:22:40,294 TRACE [org.hibernate.jdbc.AbstractBatcher] preparing statement
2012-01-18 08:22:40,295 TRACE [org.hibernate.type.IntegerType] binding '28' to parameter: 1
.......
2012-01-18 08:22:40,300 DEBUG [org.hibernate.loader.Loader] result row: EntityKey[com.tests.dupliactes.EmDefinition#133]
...
2012-01-18 08:22:40,301 DEBUG [org.hibernate.loader.Loader] result row: EntityKey[com.tests.dupliactes.EmDefinition#134]
..
2012-01-18 08:22:40,302 DEBUG [org.hibernate.loader.Loader] result row: EntityKey[com.tests.dupliactes.EmDefinition#135]
...
2012-01-18 08:22:40,303 DEBUG [org.hibernate.loader.Loader] result row: EntityKey[com.tests.dupliactes.EmDefinition#136]
...
2012-01-18 08:22:40,303 DEBUG [org.hibernate.loader.Loader] result row: EntityKey[com.tests.dupliactes.EmDefinition#137]
...
2012-01-18 08:22:40,304 DEBUG [org.hibernate.loader.Loader] result row: EntityKey[com.tests.dupliactes.EmDefinition#138]
....
2012-01-18 08:22:40,304 DEBUG [org.hibernate.loader.Loader] found row of collection: [com.tests.dupliactes.CardType.emColl#28]
2012-01-18 08:22:40,304 TRACE [org.hibernate.engine.loading.CollectionLoadContext] starting attempt to find loading collection [[com.tests.dupliactes.CardType.emColl#28]]
2012-01-18 08:22:40,304 TRACE [org.hibernate.engine.loading.LoadContexts] attempting to locate loading collection entry [CollectionKey[com.tests.dupliactes.CardType.emColl#28]] in any result-set context
2012-01-18 08:22:40,304 TRACE [org.hibernate.engine.loading.LoadContexts] collection [CollectionKey[com.tests.dupliactes.CardType.emColl#28]] not located in load context
2012-01-18 08:22:40,304 TRACE [org.hibernate.engine.loading.CollectionLoadContext] found loading collection bound to current result set processing; reading row
2012-01-18 08:22:40,304 TRACE [org.hibernate.type.IntegerType] returning '138' as column: id1_
2012-01-18 08:22:40,304 TRACE [org.hibernate.event.def.DefaultLoadEventListener] loading entity: [com.tests.dupliactes.EmDefinition#138]
2012-01-18 08:22:40,304 TRACE [org.hibernate.event.def.DefaultLoadEventListener] attempting to resolve: [com.tests.dupliactes.EmDefinition#138]
2012-01-18 08:22:40,304 TRACE [org.hibernate.event.def.DefaultLoadEventListener] resolved object in session cache: [com.tests.dupliactes.EmDefinition#138]
2012-01-18 08:22:40,304 TRACE [org.hibernate.loader.Loader] done processing result set (6 rows)
2012-01-18 08:22:40,304 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close ResultSet (open ResultSets: 1, globally: 1)
2012-01-18 08:22:40,304 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2012-01-18 08:22:40,304 TRACE [org.hibernate.jdbc.AbstractBatcher] closing statement
2012-01-18 08:22:40,305 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
2012-01-18 08:22:40,305 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
2012-01-18 08:22:40,305 TRACE [org.hibernate.loader.Loader] total objects hydrated: 0
2012-01-18 08:22:40,305 TRACE [org.hibernate.engine.loading.LoadContexts] attempting to locate loading collection entry [CollectionKey[com.tests.dupliactes.CardType.emColl#28]] in any result-set context
2012-01-18 08:22:40,305 TRACE [org.hibernate.engine.loading.LoadContexts] collection [CollectionKey[com.tests.dupliactes.CardType.emColl#28]] not located in load context
2012-01-18 08:22:40,305 TRACE [org.hibernate.engine.loading.CollectionLoadContext] removing collection load entry [org.hibernate.engine.loading.LoadingCollectionEntry<rs=com.mysql.jdbc.JDBC4ResultSet@6405b42e, coll=[com.tests.dupliactes.CardType.emColl#28]>@56de8a94]
2012-01-18 08:22:40,305 DEBUG [org.hibernate.engine.loading.CollectionLoadContext] 1 collections were found in result set for role: com.tests.dupliactes.CardType.emColl
2012-01-18 08:22:40,305 DEBUG [org.hibernate.engine.loading.CollectionLoadContext] ending loading collection [org.hibernate.engine.loading.LoadingCollectionEntry<rs=com.mysql.jdbc.JDBC4ResultSet@6405b42e, coll=[com.tests.dupliactes.CardType.emColl#28]>@56de8a94]
2012-01-18 08:22:40,305 DEBUG [org.hibernate.engine.loading.CollectionLoadContext] collection fully initialized: [com.tests.dupliactes.CardType.emColl#28]
2012-01-18 08:22:40,305 DEBUG [org.hibernate.engine.loading.CollectionLoadContext] 1 collections initialized for role: com.tests.dupliactes.CardType.emColl
2012-01-18 08:22:40,305 DEBUG [org.hibernate.engine.StatefulPersistenceContext] initializing non-lazy collections
2012-01-18 08:22:40,305 DEBUG [org.hibernate.loader.Loader] done loading collection
2012-01-18 08:22:40,305 TRACE [org.hibernate.event.def.DefaultInitializeCollectionEventListener] collection initialized
2012-01-18 08:22:40,308 INFO [STDOUT] the 'size' value is: 7
2012-01-18 08:22:40,308 INFO [STDOUT] definitionId:133
2012-01-18 08:22:40,308 INFO [STDOUT] definitionId:134
2012-01-18 08:22:40,308 INFO [STDOUT] definitionId:135
2012-01-18 08:22:40,308 INFO [STDOUT] definitionId:136
2012-01-18 08:22:40,308 INFO [STDOUT] definitionId:137
2012-01-18 08:22:40,308 INFO [STDOUT] definitionId:138
2012-01-18 08:22:40,308 INFO [STDOUT] definitionId:138
2012-01-18 08:22:40,308 INFO [STDOUT] the 'i' value is: 7
2012-01-18 08:22:40,308 TRACE [org.hibernate.transaction.CacheSynchronization] transaction before completion callback
2012-01-18 08:22:40,309 TRACE [org.hibernate.jdbc.JDBCContext] before transaction completion
2012-01-18 08:22:40,309 TRACE [org.hibernate.impl.SessionImpl] before transaction completion
2012-01-18 08:22:40,309 TRACE [org.hibernate.ejb.AbstractEntityManagerImpl] automatically flushing session
2012-01-18 08:22:40,309 TRACE [org.hibernate.impl.SessionImpl] automatically flushing session
2012-01-18 08:22:40,309 TRACE [org.hibernate.event.def.AbstractFlushingEventListener] flushing session
2012-01-18 08:22:40,309 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] processing flush-time cascades
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.CardType
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] done processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.CardType
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] done processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] done processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] done processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] done processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] done processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 TRACE [org.hibernate.engine.Cascade] done processing cascade ACTION_PERSIST_ON_FLUSH for: com.tests.dupliactes.EmDefinition
2012-01-18 08:22:40,309 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] dirty checking collections
2012-01-18 08:22:40,309 DEBUG [org.hibernate.engine.CollectionEntry] Collection dirty: [com.tests.dupliactes.CardType.emColl#28]
2012-01-18 08:22:40,310 TRACE [org.hibernate.event.def.AbstractFlushingEventListener] Flushing entities and processing referenced collections
2012-01-18 08:22:40,310 DEBUG [org.hibernate.engine.Collections] Collection found: [com.tests.dupliactes.CardType.emColl#28], was: [com.tests.dupliactes.CardType.emColl#28] (initialized)
2012-01-18 08:22:40,310 TRACE [org.hibernate.event.def.AbstractFlushingEventListener] Processing unreferenced collections
2012-01-18 08:22:40,310 TRACE [org.hibernate.event.def.AbstractFlushingEventListener] Scheduling collection removes/(re)creates/updates
2012-01-18 08:22:40,310 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 insertions, 0 updates, 0 deletions to 7 objects
2012-01-18 08:22:40,310 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 (re)creations, 1 updates, 0 removals to 1 collections
2012-01-18 08:22:40,310 DEBUG [org.hibernate.pretty.Printer] listing entities:
2012-01-18 08:22:40,310 DEBUG [org.hibernate.pretty.Printer] com.tests.dupliactes.EmDefinition{id=137, dparamId=4, cardType=com.tests.dupliactes.CardType#28}
2012-01-18 08:22:40,310 DEBUG [org.hibernate.pretty.Printer] com.tests.dupliactes.EmDefinition{id=136, dparamId=3, cardType=com.tests.dupliactes.CardType#28}
2012-01-18 08:22:40,310 DEBUG [org.hibernate.pretty.Printer] com.tests.dupliactes.EmDefinition{id=138, dparamId=5, cardType=com.tests.dupliactes.CardType#28}
2012-01-18 08:22:40,310 DEBUG [org.hibernate.pretty.Printer] com.tests.dupliactes.EmDefinition{id=133, dparamId=0, cardType=com.tests.dupliactes.CardType#28}
2012-01-18 08:22:40,311 DEBUG [org.hibernate.pretty.Printer] com.tests.dupliactes.CardType{id=28, emColl=[com.tests.dupliactes.EmDefinition#133, com.tests.dupliactes.EmDefinition#134, com.tests.dupliactes.EmDefinition#135, com.tests.dupliactes.EmDefinition#136, com.tests.dupliactes.EmDefinition#137,
com.tests.dupliactes.EmDefinition#138, com.tests.dupliactes.EmDefinition#138]}
2012-01-18 08:22:40,311 DEBUG [org.hibernate.pretty.Printer] com.tests.dupliactes.EmDefinition{id=135, dparamId=2, cardType=com.tests.dupliactes.CardType#28}
2012-01-18 08:22:40,311 DEBUG [org.hibernate.pretty.Printer] com.tests.dupliactes.EmDefinition{id=134, dparamId=1, cardType=com.tests.dupliactes.CardType#28}
2012-01-18 08:22:40,311 TRACE [org.hibernate.event.def.AbstractFlushingEventListener] executing flush
2012-01-18 08:22:40,311 TRACE [org.hibernate.jdbc.ConnectionManager] registering flush begin
2012-01-18 08:22:40,311 TRACE [org.hibernate.jdbc.ConnectionManager] registering flush end
2012-01-18 08:22:40,311 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
2012-01-18 08:22:40,311 TRACE [org.hibernate.event.def.AbstractFlushingEventListener] post flush
2012-01-18 08:22:40,335 TRACE [org.hibernate.impl.SessionImpl] closing session
2012-01-18 08:22:40,335 TRACE [org.hibernate.jdbc.ConnectionManager] connection already null in cleanup : no action
2012-01-18 08:22:40,335 TRACE [org.hibernate.transaction.CacheSynchronization] transaction after completion callback, status: 3
2012-01-18 08:22:40,335 TRACE [org.hibernate.jdbc.JDBCContext] after transaction completion
2012-01-18 08:22:40,335 TRACE [org.hibernate.impl.SessionImpl] after transaction completion
The line 2012-01-18 08:22:40,311 DEBUG [org.hibernate.pretty.Printer] com.tests.dupliactes.CardType{id=28, emColl=[com.tests.dupliactes.EmDefinition#133, com.tests.dupliactes.EmDefinition#134, com.tests.dupliactes.EmDefinition#135, com.tests.dupliactes.EmDefinition#136, com.tests.dupliactes.EmDefinition#137,
com.tests.dupliactes.EmDefinition#138, com.tests.dupliactes.EmDefinition#138]} has duplicated objects!
My question is why the returned value is 7. Whats more : take a look at my comments in code of SessionBean1. When I add printing cardType.getEmColl().size() in this specified place the collection size and returned value is always 6. How to solve this issue without using flush or refresh??