【问题标题】:Hibernate Model: set default @ManyToOne value of a Child ClassHibernate 模型:设置子类的默认 @ManyToOne 值
【发布时间】:2014-08-18 05:39:04
【问题描述】:

我有具有@ManyToOne 字段角色的类用户。

@Entity 
@Table(name="USERS")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorValue("ROLE_ADMIN")
@DiscriminatorColumn (name="ROLENAME", discriminatorType= DiscriminatorType.STRING, length=20)
public class User extends BaseEntity implements UserDetails {
    // all others fields like username, password,...

    @ManyToOne
    @JoinColumn(name = "role_id", referencedColumnName="id") 
    @NotNull(message = "ROLE field is mandatory")
    private Role role;

    //getter and setter
}

我有许多扩展用户的类:UserSeller、UserClient、UserOffice....

@Entity
    @DiscriminatorValue("ROLE_SELLER")
    @AttributeOverride(name = "role", column = @Column(name = "role_id"))
    public class UserSeller extends User {

       //additional fields like CompanyId,...

       //getter & setter
    }

我有一个面板,我可以在其中插入/编辑/删除所有类型的用户, 但我还必须有“n”面板:每种用户都有一个。

当我在这些面板中时,我希望能够插入这些 UserSeller 而无需 放置一个选择角色的位置,但我想将此角色设置为默认值。

• 我尝试在 UserSeller 中放置一个构造函数

@Entity
@DiscriminatorValue("ROLE_SELLER")
@AttributeOverride(name = "role", column = @Column(name = "role_id"))
public class UserSeller extends User {

    @Transient
    RoleService roleService;

    @Transient
    User user = new User();


    public UserSeller()
    {
        super(); 
        try
        {
            this.setRole(roleService.getRole("ROLE_SELLER"));
        }
        catch (RecordNotFoundException e)
        {

        }
    }

但我得到这个错误:

Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister

• 我尝试将用户对象传递给构造函数:

public UserSeller(User user)

在控制器中我这样做:

 User user = new User();
 UserSeller seller = new UserSeller(user);
 model.addAttribute("seller", seller);

但我收到此错误:

实体没有默认构造函数:com.machinet.model.UserVenditore

  • 如果在 UserSeller 中我再次声明 Role 字段,我会收到错误 “重新定义的列”....

  • 最后我发现这可能是我的解决方案(在 UserSeller 类):

    @PrePersist
    public void prePersist() {
            try
            {
                this.setRole(roleService.getRole("ROLE_SELLER"));
            }
            catch (RecordNotFoundException e)
            {
    
            }           
        }
    

但是当我在 UserSeller 面板中并尝试添加新的卖家时,它并没有使用默认角色并且验证失败。

我想知道我该怎么做:我希望我的 UserSeller、UserClient、... 在我插入新记录时有一个默认值。

我真的需要在控制器中执行此操作吗?这是唯一的方法吗?因为对于像我这样的初学者来说,它看起来并不那么优雅的解决方案:

UserVenditore venditore = new UserVenditore();
try
{
    venditore.setRole(roleService.getRole("ROLE_VENDITORE"));
}
catch (RecordNotFoundException ex)
{

}
model.addAttribute("venditore", venditore);

编辑:最后一个解决方案也不起作用:验证失败!

感谢您的任何建议!

【问题讨论】:

  • 附带说明,通常最好将模型和服务分开。在实体类中拥有 RoleService 是 IMO 的不良做法。
  • 感谢@JamesB 的建议。得到这些建议总是好的

标签: java hibernate default-value class-hierarchy


【解决方案1】:

目前,我只找到了这个解决方案(在 ControllerClass 中):

  • 在@ModelAttribute 之前删除了@Valid
  • 我手动设置角色
  • 我手动验证对象

    @RequestMapping(value = "/add", method = RequestMethod.POST) public String addedSeller(@ModelAttribute UserSeller 卖家, BindingResult 结果,RedirectAttributes redirectAttrs) {

    logger.info("IN: Seller/add-POST"); 
    
    //set role
    try
    {
        seller.setRole(roleService.getRole("ROLE_SELLER"));
    }
    catch (RecordNotFoundException ex)
    {
    
    }        
    
    //validation
    validator.validate(seller, result);
    
    if (result.hasErrors()) {
        logger.info("Seller-add error: " + result.toString());
        redirectAttrs.addFlashAttribute("org.springframework.validation.BindingResult.seller", result);            
        redirectAttrs.addFlashAttribute("seller", seller);
    
    } else {
    
        try
        {
            SellerService.addSeller(seller);
    
            //message to the user
            String message = "Seller added!";           
            redirectAttrs.addFlashAttribute("message", message);
            redirectAttrs.addFlashAttribute("message_class", "alert-success");      
        }
        catch (DuplicateRecordException e)
        {
            //the username already exists
    
            //message to the user
            String message = "Already exists an user with this USERNAME";           
            redirectAttrs.addFlashAttribute("message", message);
            redirectAttrs.addFlashAttribute("message_class", "alert-danger");         
    
            redirectAttrs.addFlashAttribute("seller", seller);
        }
    }   
    
    return "redirect:/sellers/list";
    

    }

【讨论】:

  • 另一个提示:将设置默认角色和验证卖家的所有逻辑推送到 SellerService 中,这就是它的用途。想象一下有另一段代码调用服务并希望应用相同的逻辑。
猜你喜欢
  • 2021-03-29
  • 2022-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 2014-12-05
相关资源
最近更新 更多