-->
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.  [ 4 posts ] 
Author Message
 Post subject: Composite keys unidirectional relationship
PostPosted: Wed Mar 11, 2009 8:39 am 
Beginner
Beginner

Joined: Tue Mar 10, 2009 11:50 pm
Posts: 23
Hi, I have the below model

ServiceDetails Class

@Entity
@Table(name = "service_details")
@AssociationOverrides( {
@AssociationOverride( name="id.serviceId", joinColumns = @JoinColumn(name = "Service_Id")),
@AssociationOverride( name="id.bundleId", joinColumns = @JoinColumn(name = "Bundle_Id"))
})
public class ServiceDetailsVO implements java.io.Serializable {

private ServiceDetailsId id;
private Boolean enabled;
private Float unitPrice;


public ServiceDetailsVO() {
}

public ServiceDetailsVO(ServiceDetailsId id) {
this.id = id;
}

@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name = "serviceId", column = @Column(name = "Service_Id", nullable = false)),
@AttributeOverride(name = "bundleId", column = @Column(name = "Bundle_Id", nullable = false)) })
public ServiceDetailsId getId() {
return this.id;
}

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


@Column(name = "Enabled")
public Boolean getEnabled() {
return this.enabled;
}

public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}

@Column(name = "Unit_Price", precision = 7)
public Float getUnitPrice() {
return this.unitPrice;
}

public void setUnitPrice(Float unitPrice) {
this.unitPrice = unitPrice;
}

}

Composite Key

@Embeddable
public class ServiceDetailsId implements java.io.Serializable {

private ServiceModelVO serviceModel;
private BundleVO bundle;

public ServiceDetailsId() {
}

/**
* @return the bundle
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "Bundle_Id", nullable = false, insertable = false, updatable = false)
public BundleVO getBundle() {
return bundle;
}

/**
* @param bundle the bundle to set
*/
public void setBundle(BundleVO bundle) {
this.bundle = bundle;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "Service_Id", nullable = false, insertable = false, updatable = false)
public ServiceModelVO getServiceModel() {
return this.serviceModel;
}

public void setServiceModel(ServiceModelVO serviceModel) {
this.serviceModel = serviceModel;
}

BundleVO class

@Entity
@Table(name = "bundle")
public class BundleVO implements java.io.Serializable {

private Long bundleId;
private String bundleName;
private Float basePrice;

private Set<ServiceDetailsVO> serviceDetails = new HashSet<ServiceDetailsVO>(0);

public BundleVO() {
}

public BundleVO(Long bundleId) {
this.bundleId = bundleId;
}



@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "Bundle_Id", unique = true, nullable = false)
public Long getBundleId() {
return this.bundleId;
}

public void setBundleId(Long bundleId) {
this.bundleId = bundleId;
}


@Column(name = "Bundle_Name", length = 50)
public String getBundleName() {
return this.bundleName;
}

public void setBundleName(String bundleName) {
this.bundleName = bundleName;
}

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "id.bundle")
public Set<ServiceDetailsVO> getServiceDetails() {
return this.serviceDetails;
}

public void setServiceDetails(Set<ServiceDetailsVO> serviceDetails) {
this.serviceDetails = serviceDetails;
}

public void addServiceDetail(ServiceDetailsVO serviceDetailsVO) {

serviceDetailsVO.getId().setBundle(this);
this.serviceDetails.add(serviceDetailsVO);

}

//Creating a bundle

BundleVO bundleVO = new BundleVO();

//Basic attributes
bundleVO.setBundleName("Pack 1");
bundleVO.setBasePrice(new Float("23.35"));
bundleVO.setDescription("Pack 1 - desc");
bundleVO.setIsPublished(false);

//Reference attributes
ServiceDetailsVO serviceDetailsVO = new ServiceDetailsVO();
serviceDetailsVO.setEnabled(false);
serviceDetailsVO.setUnitPrice(new Float("20.00"));
ServiceDetailsId serviceDetailsId = new ServiceDetailsId();
serviceDetailsId.setServiceModel(serviceModelDAO.readServiceModel(new Long(5)));
serviceDetailsVO.setId(serviceDetailsId);

bundleDAO.createBundle(bundleVO);

This is property inserting a bundle with cascade to service details, but i want to achieve the same using unidirectional association i.e Service Details should not contain reference to Bundle. Please let me know how to provide mapping for the same

I tried giving
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="Bundle_Id" , nullable = false)
public Set<ServiceDetailsVO> getServiceDetails() {
return this.serviceDetails;
}

and removed Bundle reference from ServiceDetailsId

but it throws an error saying no mapping for column Bundle_Id


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 11, 2009 10:38 am 
Newbie

Joined: Thu Apr 20, 2006 5:31 am
Posts: 3
Rephrasing my above question.

I have a BundleVO which needs one-to-Many unidirectional association with ServiceDetailsVO. ServiceDetailsVO contains composite primary key, one of the key being supplied from other model object

When i give the below association in BundleVO

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="Bundle_Id", nullable = false)
public Set<ServiceDetailsVO> getServiceDetails() {
return this.serviceDetails;
}


It throws me the exception
Caused by: org.hibernate.MappingException: Unable to find column with logical name: Bundle_Id in service_details


ServiceDetailsVO

Entity
@Table(name = "service_details")
public class ServiceDetailsVO implements java.io.Serializable {

private ServiceDetailsId id;

//Other fields


}

@Embeddable
public class ServiceDetailsId implements java.io.Serializable {

//Other model object giving one of the composite id
private ServiceModelVO serviceModel;

// No reference to BundleVO - i dont want to retain this bi-directional relationship with bundle
//private BundleVO bundle;
}

Please let me know how to provide the mappings in such a way that unidirectional for object with composite key is achieved

_________________
VINOD JAYENDRA


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 11, 2009 10:38 am 
Newbie

Joined: Thu Apr 20, 2006 5:31 am
Posts: 3
Rephrasing my above question.

I have a BundleVO which needs one-to-Many unidirectional association with ServiceDetailsVO. ServiceDetailsVO contains composite primary key, one of the key being supplied from other model object

When i give the below association in BundleVO

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="Bundle_Id", nullable = false)
public Set<ServiceDetailsVO> getServiceDetails() {
return this.serviceDetails;
}


It throws me the exception
Caused by: org.hibernate.MappingException: Unable to find column with logical name: Bundle_Id in service_details


ServiceDetailsVO

Entity
@Table(name = "service_details")
public class ServiceDetailsVO implements java.io.Serializable {

private ServiceDetailsId id;

//Other fields


}

@Embeddable
public class ServiceDetailsId implements java.io.Serializable {

//Other model object giving one of the composite id
private ServiceModelVO serviceModel;

// No reference to BundleVO - i dont want to retain this bi-directional relationship with bundle
//private BundleVO bundle;
}

Please let me know how to provide the mappings in such a way that unidirectional for object with composite key is achieved

_________________
VINOD JAYENDRA


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 11, 2009 1:06 pm 
Newbie

Joined: Mon Jan 15, 2007 1:18 pm
Posts: 8
Vinu,

I'm not that familiar with the annotations approach, as I use configuration files instead, but I've managed to join collections of entities with composite primary key by creating a component in the "one" side of the association with all the columns required for the match. Then use this component in <key> element through the property-ref attribute.

See below the example for a Map (a Set should be the very similar):
Code:
    <component name="foreignKey" class="BId" access="field">
      <property name="type" column="TYPE" insert="false" update="false" />
      <property name="code" column="CODE" insert="false" update="false" />
    </component>

    <map name="descriptions">
      <key property-ref="foreignKey">
        <column name="TYPE" />
        <column name="CODE" />
      </key>
      <map-key formula="LANG" type="string" />
      <one-to-many class="B" />
    </map>


where the primary key for class B is defined as:
Code:
    <composite-id name="id" class="BId">
      <key-property name="language" column="LANG"/>
      <key-property name="type" column="TYPE"/>
      <key-property name="code" column="CODE" />
    </composite-id></class>


If your composite ID has only 2 fields, then you can create a property instead of a component, as you will only want to match one column (otherwise you will have a one-to-one).

For more details you can check my original post (even though it was about a different problem) at:
http://forum.hibernate.org/viewtopic.php?t=995290

Hope this helps,
Juan


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.